我的程序的目标是使用select来管理多个套接字。但是,我想先用一个插座尝试一下。现在,我面临的问题是,最初客户端将数据发送到服务器,服务器接收并显示它,但是当客户端再次发送一些数据时,服务器代码仍然处于选择命令。
这里有一些片段可以让你了解我如何初始化套接字。
if((master_socket = socket(PF_INET, SOCK_STREAM, 0)) < 0)
{
exit(1);
}
if((bind(master_socket, (struct sockaddr *)&req, sizeof(req))) < 0)
{
exit(1);
}
listen(master_socket, 5);
FD_SET(master_socket,&listening);
/* wait for connection, then receive and print text */
len = sizeof(struct sockaddr);
while(1)
{
FD_ZERO(&listening); //Flush out everything in socket
FD_SET(master_socket,&listening); // Add master
if(f_client>0) // Add client if any
{
FD_SET(f_client,&listening);
}
printf("Checking for new connection \n");
//Timeout is null, so waiting indefinitely
rc = select(FD_SETSIZE, &listening, NULL, NULL, NULL);
if (FD_ISSET(master_socket, &listening))
{
printf("Master side invoked\n");
if((f_client = accept(master_socket, (struct sockaddr *)&req, &len)) < 0)
{
exit(1);
}
}
else if (FD_ISSET(f_client,&listening))
{
if ((valread = read( f_client , buf, 1024)) == 0)
{
close(f_client);
f_client=0;
}
else
{
fputs(buf, stdout);
}
}
}
基本上在上面的程序中,它连接到服务器,维护客户端f_client
的文件描述符并添加它。并且在每一轮中,它清除套接字,添加主套接字和客户端套接字(如果有),然后检查。这里的问题是,它第一次工作,但第二次客户端发送一些数据。它会挂起rc = select(FD_SETSIZE, &listening, NULL, NULL, NULL);
我不明白这里有什么问题。有人可以帮忙吗?
答案 0 :(得分:4)
if ((valread = read( f_client , buf, 1024)) == 0)
{
close(f_client);
f_client=0;
}
else
{
fputs(buf, stdout);
}
此代码已损坏。 fputs
函数只能 与C风格的字符串一起使用。你只有没有特定结构的任意数据。由于您忽略了valread
,因此您也不知道您读取了多少字节。 (考虑一下,fputs
怎么可能知道要输出多少字节?这些信息仅在valread
中,并且您不会将该信息传递给它。)
您已经收到了数据,这个破损的代码只是把它扔掉了。如果您记录valread
,则在拨打read
之前,您在select
的最后一次通话中确实已经看过它。
而不是fputs
,您可以使用以下内容:
for (int i = 0; i < valread; ++i)
putchar(buf[i]);