dimanche 22 février 2015

socket file descriptors are the same among different processes


I have a simple server-client program. When I invoke the clients in separate ./client calls, each client is assigned a different file descriptor for its connection to server. But when I call them through the following bash script, all clients get the same socket fd:



for i in {1..5}
do
./client &
done


Here's my code:


client.cpp



int main (int argc, char *argv[]) {
int sockfd;
std::string ip = "127.0.0.1";
char temp_char;

establish_tcp_connection(ip.c_str(), 45678, &sockfd);
printf("Client connected to server on sock %d", sockfd);

// make sure that the socket is not closed before other clients start
// so, just send a dummy char back and forth
sock_sync_data (sockfd, 1, "W", &temp_char);

return 0;
}


Server.cpp



int main (int argc, char *argv[]) {
int CLIENTS_CNT = 2;
int server_sockfd;
char temp_char;
int sockfd[CLIENTS_CNT];

struct sockaddr_in serv_addr, returned_addr;
socklen_t len = sizeof(returned_addr);

server_sockfd = socket (AF_INET, SOCK_STREAM, 0);

memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(45678);

bind(server_sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr));
listen (server_sockfd, CLIENTS_CNT);

for (int c = 0; c < CLIENTS_CNT; c++){
sockfd[c] = accept (server_sockfd, (struct sockaddr *) &returned_addr, &len);
printf("For client %d on sock %d", c, sockfd[c]);
}

for (int c = 0; c < CLIENTS_CNT; c++) {
/* just send a dummy char back and forth */
sock_sync_data (sockfd[c], 1, "W", &temp_char);
}

close(server_sockfd);
}


And here's my util code:



int sock_connect (std::string servername, int port) {
int sockfd, n;
struct sockaddr_in serv_addr;
struct hostent *server;

sockfd = socket(AF_INET, SOCK_STREAM, 0);

memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(port);
serv_addr.sin_addr.s_addr = inet_addr((char*)servername.c_str());
if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) LESS_THAN_SIGN 0){
printf("ERROR connecting");
return -1;
}
return sockfd;
}

int establish_tcp_connection(std::string remote_ip, int remote_port, int *sockfd) {
*sockfd = sock_connect (remote_ip, remote_port);
if (*sockfd < 0) {
printf("failed to establish TCP connection to server ");
return -1;
}
return 0;
}



Aucun commentaire:

Enregistrer un commentaire