Jump to content
Forumu Destekleyenlere Katılın ×
Paticik Forumları
2000 lerden beri faal olan, çok şukela bir paylaşım platformuyuz. Hoşgeldiniz.

valgrind ve unix soket accept fonksiyonuyla ilgili ufak sorular


Fly

Öne çıkan mesajlar

elimde kabaca şöyle bir loop var :


volatile sig_atomic_t a;
int cn;
...
while(a) {
if ((cn=accept(ana_soket,hede hödö))!=-1) -yeni thread-
else -hata-
}
..


şimdi sigterm/usr1 gelince a'yı sıfır yaptırtıp döngüyü bitirmek istiyorum, zira şimdiye kadar sinyal alınca yaptığı tek iş kapanmak veya ana looptan bağımsız iş yapan programlarda pause veya sleep ile kotarabiliyorum

lakin bunda tam olarak ne hatası çıkıyor onu da anlamadım da (eclipse' in debuggerında suspended : signal diyor sadece, segv mi başka bir şey mi görünmüyor, detayına bakmayı bilen varsa şahane olur) sinyali aldığı anda accept satırı hata veriyor. soketi sinyalle birlikte kapayayım kapamayayım aynı şey. hatam nerede ?

ikinci olarak kullanan var mı bilmiyorum da valgrindde çalışan programa sigterm gönderip bitirmem gerekiyor ki açılan thread başına ne kadar leak error var göreyim, lakin sinyali programa aktarmayı yapamadım, bunu da bilen varsa diye soracaktım.
Link to comment
Sosyal ağlarda paylaş

Bence accept() dondukten -1 dondukten sonra error numarasina yada perror() fonksiyonuna sokmalisinki verdigi hatayi daha anlasilir hale gelsin.
Eger sinyal aldiktan sonra accept'den cikmak istiyorsan aklima ilk gelen methodu soyliyim, socket descriptoru'unu non-blocking yapip (O_NONBLOCK), sinyal fonksyionununda ortak erisip degistirebilcegi bir degiskeni kontrol etmek olurdu, tabi bu biraz spin attirmak oluyor ve guzel bir method degil.
Diger method select/poll'dan birisi. Soketi bu sistem cagrilariyla dinlersen, timeout degeri belirleyebilir ve bu ortak olan sinyal degiskenini kontrol edip istedigini yapabilirsin.
Daha da guzeli select() 'e exceptfds verebiliyorsun yani exception file descriptor list. Eger bu exceptfds deki file descriptor'a exception yarattirabilirsen (sinyal fonksiyonunu icinden soket file descriptor'u kapatmak gibi) istedigin olur heralde.
Bu arada sendeki accept() in -1 donmemesi lazim sinyal aldigin, internetten alip editledigim su kod gayet duzgun calisiyor.



#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#include <signal.h>

#define SOCKET_ERROR -1
#define BUFFER_SIZE 100
#define MESSAGE "This is the message I'm sending back and forth"
#define QUEUE_SIZE 5

void catch_int(int);


int main(int argc, char* argv[])
{
signal(SIGINT, catch_int);
signal(SIGTERM, catch_int);

int hSocket,hServerSocket; /* handle to socket */
struct hostent* pHostInfo; /* holds info about a machine */
struct sockaddr_in Address; /* Internet socket address stuct */
int nAddressSize=sizeof(struct sockaddr_in);
char pBuffer[BUFFER_SIZE];
int nHostPort;

if(argc < 2)
{
printf("nUsage: server host-portn");
return 0;
}
else
{
nHostPort=atoi(argv[1]);
}

printf("nStarting server");

printf("nMaking socket");
/* make a socket */
hServerSocket=socket(AF_INET,SOCK_STREAM,0);

if(hServerSocket == SOCKET_ERROR)
{
printf("nCould not make a socketn");
return 0;
}

/* fill address struct */
Address.sin_addr.s_addr=INADDR_ANY;
Address.sin_port=htons(nHostPort);
Address.sin_family=AF_INET;

printf("nBinding to port %d",nHostPort);

/* bind to a port */
if(bind(hServerSocket,(struct sockaddr*)&Address,sizeof(Address))
== SOCKET_ERROR)
{
printf("nCould not connect to hostn");
return 0;
}
/* get port number */
getsockname( hServerSocket, (struct sockaddr *) &Address,(socklen_t *)&nAddressSize);
printf("opened socket as fd (%d) on port (%d) for stream i/on",hServerSocket, ntohs(Address.sin_port) );

printf("Servern
sin_family = %dn
sin_addr.s_addr = %dn
sin_port = %dn"
, Address.sin_family
, Address.sin_addr.s_addr
, ntohs(Address.sin_port)
);


printf("nMaking a listen queue of %d elements",QUEUE_SIZE);
/* establish listen queue */
if(listen(hServerSocket,QUEUE_SIZE) == SOCKET_ERROR)
{
printf("nCould not listenn");
return 0;
}

for(;;)
{
printf("nWaiting for a connectionn");
/* get the connected socket */
hSocket=accept(hServerSocket,(struct sockaddr*)&Address,(socklen_t *)&nAddressSize);

printf("nGot a connection");
strcpy(pBuffer,MESSAGE);
printf("nSending "%s" to client",pBuffer);
/* number returned by read() and write() is the number of bytes
** read or written, with -1 being that an error occured
** write what we received back to the server */
write(hSocket,pBuffer,strlen(pBuffer)+1);
/* read from socket into buffer */
read(hSocket,pBuffer,BUFFER_SIZE);

if(strcmp(pBuffer,MESSAGE) == 0)
printf("nThe messages match");
else
printf("nSomething was changed in the message");

printf("nClosing the socket");
/* close socket */
if(close(hSocket) == SOCKET_ERROR)
{
printf("nCould not close socketn");
return 0;
}
}
}

void catch_int(int sig_num)
{
printf("caught int/term signal no : %dn", sig_num);
}

Link to comment
Sosyal ağlarda paylaş

×
×
  • Yeni Oluştur...