LINUX.ORG.RU

Подскажите кто-нибудь (socket)


0

0

Проблема такая:
есть сервер и куча клиентов
везде Linux (как на сервере, так и на клиентах)
клиент сам действует как сервер, то есть:
оба (клиент и сервер) создают соединение : create_connection() - см ниже..
оба запускают wait_packet()
клиент отсылает данные серверу: send_packet().
потом обратно отсылается результат
то есть всё симметрично, кроме того, что клиентов много, а сервер один .

Так вот в функции send_packet на сервере растут номера создаваемых дескрипторов! В результате после 1024-х он валится... На клиенте такого не наблюдается...

Никак не пойму в чём дело

Заранее признателен за помощь.

anonymous

собственно код

#include <netinet/in.h> #include <sys/socket.h> #include <sys/time.h> #include <string.h> #include <unistd.h> #include <netdb.h> #include <stdlib.h> #include <fcntl.h>

#include "log.h" #include "packet.h"

/* Wait packet 'pack' from socket 's0' and decrypt it using key 'key' Return non-zero if error */ int wait_packet (int s0, packet * pack, MCRYPT * key) { int s1, res; struct sockaddr_in peeraddr; socklen_t peeraddr_len;

s1 = accept (s0, (struct sockaddr *) &peeraddr, &peeraddr_len); if (s1 < 0) { error (2, _("Cannot accept")); close (s1); return -3; } res = read (s1, pack, sizeof (packet)); // res should be sizeof (packet) if (res != sizeof (packet)) { error (2, _("Read error")); close (s1); return -1; } decrypt (key, (char *) pack, sizeof (packet)); if (scmp (pack->key)) { error (2, _("Wrong packet")); return -1; } close (s1); return 0; }

int create_connection (int port) { struct sockaddr_in myaddr; int s0, res;

// Create a socket s0 = socket (AF_INET, SOCK_STREAM, 0);

if (s0 < 0) { error (1, _("Cannot create a socket")); return 0; }

// Fill in the address structure containing self address memset (&myaddr, 0, sizeof (struct sockaddr_in)); myaddr.sin_family = AF_INET; myaddr.sin_port = htons (port); // Port to listen myaddr.sin_addr.s_addr = htonl (INADDR_ANY);

// Bind a socket to the address res = bind (s0, (struct sockaddr *) &myaddr, sizeof (myaddr)); if (res < 0) { error (1, _("Cannot bind a socket")); return 0; }

// Now, listen for a connection res = listen (s0, 5); // "5" is the maximal length of the queue if (res < 0) { error (1, _("Cannot listen")); return 0; }

return s0; }

anonymous
()
Ответ на: комментарий от anonymous

#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <string.h>
#include <unistd.h>
#include <netdb.h>
#include <stdlib.h>
#include <fcntl.h>

#include "log.h"
#include "packet.h"

/* Wait packet 'pack' from socket 's0' and decrypt it using key 'key'
Return non-zero if error */
int
wait_packet (int s0, packet * pack, MCRYPT * key)
{
int s1, res;
struct sockaddr_in peeraddr;
socklen_t peeraddr_len;


s1 = accept (s0, (struct sockaddr *) &peeraddr, &peeraddr_len);
if (s1 < 0)
{
error (2, _("Cannot accept"));
close (s1);
return -3;
}
res = read (s1, pack, sizeof (packet));
// res should be sizeof (packet)
if (res != sizeof (packet))
{
error (2, _("Read error"));
close (s1);
return -1;
}
decrypt (key, (char *) pack, sizeof (packet));
if (scmp (pack->key))
{
error (2, _("Wrong packet"));
return -1;
}
close (s1);
return 0;
}


int
create_connection (int port)
{
struct sockaddr_in myaddr;
int s0, res;

// Create a socket
s0 = socket (AF_INET, SOCK_STREAM, 0);

if (s0 < 0)
{
error (1, _("Cannot create a socket"));
return 0;
}

// Fill in the address structure containing self address
memset (&myaddr, 0, sizeof (struct sockaddr_in));
myaddr.sin_family = AF_INET;
myaddr.sin_port = htons (port); // Port to listen
myaddr.sin_addr.s_addr = htonl (INADDR_ANY);

// Bind a socket to the address
res = bind (s0, (struct sockaddr *) &myaddr, sizeof (myaddr));
if (res < 0)
{
error (1, _("Cannot bind a socket"));
return 0;
}

// Now, listen for a connection
res = listen (s0, 5); // "5" is the maximal length of the queue
if (res < 0)
{
error (1, _("Cannot listen"));
return 0;
}

return s0;
}

anonymous
()
Ответ на: комментарий от anonymous


/* Encrypt packet 'pack' using key 'key' and send it to port 'port'
of a host 'hostbame' */
int
send_packet (packet * pack, char *hostname, int port, MCRYPT * key)
{
struct timeval timeout;
struct sockaddr_in peeraddr;
struct sockaddr_in myaddr;
int res, s0;
int err; // For function gethostbyname_r
struct hostent host;
struct hostent *host2;
char buf[BUF_LEN];

s0 = socket (AF_INET, SOCK_STREAM, 0);
if (s0 < 0)
{
error (2, _("Cannot create a socket"));
return 0;
}
log (4, _("Create socket fd = %d"), s0);

memset (&myaddr, 0, sizeof (struct sockaddr_in));
myaddr.sin_family = AF_INET;
myaddr.sin_addr.s_addr = htonl (INADDR_ANY);

res = bind (s0, (struct sockaddr *) &myaddr, sizeof (myaddr));
if (res < 0)
{
error (2, _("Cannot bind a socket"));
close (s0);
return 0;
}

// Fill in the address of server
memset (&peeraddr, 0, sizeof (peeraddr));

// Resolve the server address (convert from symbolic name to IP number)
if (gethostbyname_r (hostname, &host, buf, BUF_LEN, &host2, &err))
{
error (2, _("Cannot get host address"));
close (s0);
return 0;
}

peeraddr.sin_family = AF_INET;
peeraddr.sin_port = htons (port);

// Write resolved IP address of a server to the address structure
memmove (&(peeraddr.sin_addr.s_addr), host.h_addr_list[0], 4);

log (2, _("Connection to remote host %s begins"), hostname);

// Create nonblocking socket
res = fcntl (s0, F_SETFL, O_NONBLOCK);
if (res < 0)
{
error (1, _("Cannot create nonblocking socket"));
close (s0);
return 0;
}

// Connect to a remote server
res = connect (s0, (struct sockaddr *) &peeraddr, sizeof (peeraddr));
if (res < 0)
{
int ret;
fd_set (wfds);
timeout.tv_sec = 0;
timeout.tv_usec = 1000000;
FD_ZERO (&wfds);
FD_SET (s0, &wfds);
FD_SET (s0, &wfds);

ret = select (s0 + 1, NULL, (void *) &wfds, NULL, &timeout);
if (ret <= 0)
{
error (2, _("Connection to host %s failed"), hostname);
FD_CLR (s0, &wfds);
close (s0);
return 0;
}
FD_CLR (s0, &wfds);
}
log (2, _("Connection to remote host %s success"), hostname);

strcpy (pack->key, PACKET_KEY);
encrypt (key, (char *) pack, sizeof (packet));

res = write (s0, pack, sizeof (packet));
if (res < 0)
error (1, _("Cannot write"));

/*
* Reset 'select' timer (???)
*/

usleep (0);

close (s0);
return 0;
}

anonymous
()
Ответ на: комментарий от anonymous

В send_packet() вроде как все в норме
может стоит проверить свои функции, которые вызываются в send_packet()?
Может в них где-то забыл закрыть дескриптор?

Dead ★★★★
()
Ответ на: комментарий от anonymous

У тебя как минимум 1 потенциальный лик сокета в wait_packet() - см фрагмент проверки, где выводится Wrong packet - там идет возврат без закрытия s1

Еще два лика в create_conenction() - возле cannot bind и cannot listen

В send_packet два FD_SET (s0, &wfds) - ну да это твое дело.

И еще убери bind() оттуда, не нужен он при твоей манере его потребления.

no-dashi ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.