c socket prog-select()问题
我是网络编程新手。我必须用C编写一个简单的客户机/服务器程序。服务器将侦听连接,客户机将连接到服务器,发送消息,并从客户机接收回显。我们必须使用select来更新它,以同时处理从服务器进程到多个客户端的连接。我试图按照指示在客户端实现select,但我认为在ifFD_ISSETclientSockfd和readfds部分的客户端上有一个无限循环 这是服务器c socket prog-select()问题,c,sockets,select-function,C,Sockets,Select Function,我是网络编程新手。我必须用C编写一个简单的客户机/服务器程序。服务器将侦听连接,客户机将连接到服务器,发送消息,并从客户机接收回显。我们必须使用select来更新它,以同时处理从服务器进程到多个客户端的连接。我试图按照指示在客户端实现select,但我认为在ifFD_ISSETclientSockfd和readfds部分的客户端上有一个无限循环 这是服务器 //server.c #include <stdio.h> #include <unistd.h> #includ
//server.c
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/socket.h>
#include <resolv.h>
#include <arpa/inet.h>
#include <errno.h>
const int ASSIGNED_PORT = 17000;
const int BUF_SIZE = 512;
int main() {
int serverfd, clientfd;
struct sockaddr_in serverSock; //NOTE: a pointer to sockaddr_in can be cast to a pointer to
// a struct sockaddr - useful for connect()
char buf[BUF_SIZE];
int errorCheck, msgLength;
//create socket with error checking (-1 ret on error)
serverfd = socket(AF_INET, SOCK_STREAM, 0);
if(serverfd < 0 )
{
perror("socket failed.");
exit(errno);
}
//assign sockaddr_in info for server
bzero(&serverSock, sizeof(serverSock)); //set to all 0's
serverSock.sin_family = AF_INET;
serverSock.sin_addr.s_addr = htonl(INADDR_ANY);
serverSock.sin_port = htons(ASSIGNED_PORT);
//bind a name to the socket with error checking (0 ret on success)
errorCheck = bind(serverfd, (struct sockaddr*)&serverSock, sizeof(serverSock));
if(errorCheck < 0 )
{
perror("bind failed.");
exit(errno);
}
//listen for connections with error checking (0 ret on success)
errorCheck = listen(serverfd, 10);
if(errorCheck < 0 )
{
perror("listen failed.");
exit(errno);
}
printf("Listening for connections. Enter CNTRL-c to kill server.\n");
//create infinite loop to accept, read, write, and close connections with error hecking
while(1)
{
//accept the connection from the client
clientfd = accept(serverfd, 0, 0);
if(clientfd == -1)
{
perror("error accepting connection.");
exit(errno);
}
//read data from the client
bzero(buf, BUF_SIZE);
msgLength = read(clientfd, buf, BUF_SIZE-1);
if(msgLength == -1)
{
perror("error reading from client");
close(clientfd);
close(serverfd);
exit(errno);
}
if(buf[0] '\0')
{
printf("connection closing");
exit(0);
}
//print what the client sent
printf("Message from client: %s\n", buf);
//echo back what the client sent
errorCheck = write(clientfd, buf, strlen(buf)+1);
if(errorCheck == -1 )
{
perror("error writing to client");
exit(errno);
}
//close the connection
errorCheck = close(clientfd);
if(errorCheck == -1)
{
perror("error closing connection");
exit(errno);
}
}
errorCheck = close(serverfd);
if(errorCheck==-1)
{
perror("error closing server, exiting program now");
sleep(6);
exit(errno);
}
return 0;
}
您需要在服务器端使用select来处理多个客户端,而不是在客户端。我认为客户端代码中的一个问题是,您正在传递魔法数字32进行选择。那是不对的。您应该传递的是所有套接字编号的最大值,再加上一个。例如,类似这样的内容:
int maxfd = fileno(stdin);
if (maxfd < clientSockFD) maxfd = clientSockFD;
// further maximizations for other sockets would go here, if you had any other sockets...
numfd = select(maxfd+1, &readfds, 0, 0, 0);
请正确格式化您的代码。每行之间都有大量的空行。快速查看可以发现一些问题:您的/0应该是\0两个NUL字符吗?此外,我认为如果buf[0]='\0',请注意用于字符比较的单引号。除此之外,bzero已被弃用,herror未定义。select在连接的任何一端都会有所帮助,具体取决于所需的行为。我首先在服务器端实现了select,我的老师告诉我这不是他想要的,select应该在客户端中,如果您希望一个程序同时处理多个套接字FD,则serverSelect在任何地方都不会有用。它最常用于服务器,因为服务器通常希望能够同时处理多个客户端连接,但它在客户端也很有用,就像您的情况一样,您希望同时处理stdin和TCP套接字上的输入。我感谢你的帮助。我相信我终于让它像老师希望的那样工作了。我想得太多了。@newuser12你的老师提出这个奇怪要求的原因是什么?这是常见行业实践的背对背。因此,可能一个好问题是,我应该如何测试客户端,以查看select函数是否正常工作?我想我可能会感到困惑,因为我所看到的一切都是在服务器端实现select,而不是在客户端实现select。所以,我有点困惑。此外,当我在客户端发送文本字符串时,它限制我在关闭之前只发送3个。为什么会这样?哎呀,我在代码片段中犯了一个错误,要选择的第一个参数应该是maxfd+1,而不仅仅是maxfd。我将编辑我的答案以更正。至于为什么关闭客户端的套接字,可能是因为服务器端设置为只从TCP连接读取单个流,然后关闭TCP连接。
int maxfd = fileno(stdin);
if (maxfd < clientSockFD) maxfd = clientSockFD;
// further maximizations for other sockets would go here, if you had any other sockets...
numfd = select(maxfd+1, &readfds, 0, 0, 0);