我正在檢出一個由計算器成員編寫的程序atanos關於2010年將多個客戶端連接到單個服務器時,我稍微修改了他的程序以接受來自命令的連接詳細信息行,下面是服務器和cient代碼。即使連接被接受,「recv」也不起作用
Server.c
int main(int argc, char **argv)
{
fd_set fds, readfds;
int i, clientaddrlen, portno;
int clientsock[2], rc, numsocks = 0, maxsocks = 2;
if (argc < 2){
fprintf(stderr,"ERROR, no port provided\n");
exit(1);
}
int serversock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (serversock == -1) perror("Socket");
portno = atoi(argv[1]);
struct sockaddr_in serveraddr, clientaddr;
bzero(&serveraddr, sizeof(struct sockaddr_in));
serveraddr.sin_family = AF_INET;
serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
serveraddr.sin_port = htons(portno);
if (-1 == bind(serversock, (struct sockaddr *)&serveraddr,sizeof(struct sockaddr_in))) perror("Bind");
if (-1 == listen(serversock, SOMAXCONN)) perror("Listen");
FD_ZERO(&fds);
FD_SET(serversock, &fds);
while(1) {
readfds = fds;
rc = select(FD_SETSIZE, &readfds, NULL, NULL, NULL);
if (rc == -1){
perror("Select");
break;
}
for (i = 0; i < FD_SETSIZE; i++)
{
if (FD_ISSET(i, &readfds)){
if (i == serversock){
if (numsocks < maxsocks){
clientsock[numsocks] = accept(serversock,(struct sockaddr *) &clientaddr,
(socklen_t *)&clientaddrlen);
if (clientsock[numsocks] == -1) perror("Accept");
else printf("Connection accepted\n");
FD_SET(clientsock[numsocks], &fds);
numsocks++;
}
else
printf("Ran out of socket space.\n");
}
else
{
int messageLength = 10;
char message[messageLength+1];
int numOfChRead, index = 0, limit = messageLength+1;
numOfChRead = recv(clientsock[i], message, messageLength,0);
if(numOfChRead > 0)
printf("Data Received !!! length: %d Message: %s", numOfChRead, message);
else
printf("Nothing read\n");
}
}
}
}
close(serversock);
return 0;
}
Client.c
int main(int argc, char **argv)
{
struct sockaddr_in servaddr;
struct hostent *server;
int portno, bytesSent = 0;
if (argc < 3){
fprintf(stderr,"Usage %s hostname port\n", argv[0]);
exit(0);
}
portno = atoi(argv[2]);
int sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sock == -1) perror("Socket");
server = gethostbyname(argv[1]);
if (server == NULL){
fprintf(stderr,"ERROR, no such host\n");
exit(0);
}
bzero((void *) &servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(portno);
bcopy((char *)server->h_addr,(char *)&servaddr.sin_addr.s_addr,server->h_length);
if (-1 == connect(sock, (struct sockaddr *)&servaddr, sizeof(servaddr))) perror("Connect");
while(1) {
char message[10];
fgets(message, 10, stdin);
message[10] = '\0';
bytesSent = send(sock, message, strlen(message), 0);
if(bytesSent == -1) printf("Sending failed with errno %d", errno);
else printf("Sent %d characters", bytesSent);
}
close(sock);
}
我可以看到,服務器接受多個連接,但是當我從任何客戶端的發送的消息,則服務器中的recv API不會讀取任何內容。客戶端的發送API成功,我可以看到所有的字符都被髮送了。有人可以評論嗎?
或者,他可以改變'FD_SET(clientsock [numsocks] &fds);'來'FD_SET(clientsock [numsocks],&readfds);'此外,POSIX要求是FD_SET必須是一個結構,我已經不看到一個不可複製的* nix。 – nos
POSIX強加一個結構體,它並不強制該結構體不包含指針,如果是,則通過'='的結構體複製將不會執行OP需要的結構。這就是說,我不知道這個副本不會工作的實現,有些環境提供了一個'FD_COPY' - 對於那些使用它而不是一個普通的任務可能更安全的地方 – Mat
非常感謝很多人,它幫助了很多 – Neo