我有一个简单的服务器-客户端程序。当我通过同一个 c++ 程序中的循环为所有客户端建立连接时,每个客户端都被分配了一个不同的文件描述符,用于连接到服务器。但是当我在单独的程序中建立连接时(例如使用以下脚本),所有客户端都获得相同的套接字 fd:
for i in {1..3}
do
./client &
done
第一种情况(在 for 循环中调用客户端)的输出是:
output on Server:
For client 0 on sock 3
For client 1 on sock 4
For client 2 on sock 5
output on Client-version1:
Client connected to server on sock 4
Client connected to server on sock 6
Client connected to server on sock 7
第二种情况(在单独的进程中调用)的输出是:
output on Server:
For client 0 on sock 3
For client 1 on sock 4
For client 2 on sock 5
output on Client 1-version2:
Client connected to server on sock 3
output on Client 2-version2:
Client connected to server on sock 3
output on Client 3-version2:
Client connected to server on sock 3
这是我的代码:
客户端(版本 1).cpp
int main (int argc, char *argv[]) {
int sockfd[3];
std::string ip = "127.0.0.1";
char temp_char;
for (int i = 0; i < 3; i++) {
establish_tcp_connection(ip.c_str(), 45678, &sockfd[i]);
printf("Client connected to server on sock %d", sockfd[i]);
}
// make sure that the socket is not closed before other clients start
// so, just send a dummy char back and forth
for (int i = 0; i < 3; i++)
sock_sync_data (sockfd, 1, "W", &temp_char);
return 0;
}
客户端(版本 2).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;
}
服务器.cpp
int main (int argc, char *argv[]) {
int CLIENTS_CNT = 3;
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);
}
这是我的util代码:
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;
}
最佳答案
文件描述符通常是操作系统内核为每个进程创建的文件描述符表中的一个索引。因此,它们的数字实际上是独立的,而您得到的数字 3 实际上是之后的第一个数字(0、1、2 - stdin、stdout 和 stderr 相应)。
然而,套接字伪文件可能具有跨系统全局的 inode 编号。他们更难接触到。
关于c++ - 套接字文件描述符在不同进程之间是相同的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28664364/