【发布时间】:2016-07-28 00:11:37
【问题描述】:
我正在尝试使用单个服务器和多个客户端场景制作客户端服务器聊天应用程序。我的服务器正在工作,但我无法让客户端正常工作。我正在使用 select() 函数来选择我应该是 recv() 还是 send()。这是我的客户端实现代码。
main()
{
int sockfd;
struct sockaddr_in serv_addr;
int i, sent;
char buf[100];
char buff[100];
/*
Opening a socket
Check whether opening is successful or not
*/
if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){
printf("Unable to create socket\n");
}
printf("Socket created\n");
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
serv_addr.sin_port = htons(6000);
/*
Establish a connection with the server process
*/
if((connect(sockfd, (struct socketaddr *)&serv_addr, sizeof(serv_addr)))<0){
printf("Unable to connect to server\n");
exit(0);
}
printf("Client connected\n");
while(1){
for(i=0; i<100; i++){
buf[i] = '\0';
buff[i] = '\0';
}
fd_set rfd, wfd;
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 0;
FD_ZERO( &rfd);
FD_ZERO( &wfd);
FD_SET( sockfd, &rfd);
//FD_SET( sockfd, &wfd);
FD_SET( 0, &wfd);
if( (select( sockfd + 1, &rfd, &wfd, NULL, &tv) < 0)) {
printf(" Select error \n");
exit(0);
}
if( FD_ISSET( sockfd, &rfd)) { // we got data ... need to read it
recv(sockfd, buff, 100, 0);
printf("Received result from server = %s\n",buff);
}
if( FD_ISSET( 0, &wfd)) {
fflush(stdin);
printf(">");
gets(buf);
sent = send(sockfd, buf, strlen(buf) + 1, 0);
printf("-------------Sent %d bytes to server--------------\n", sent);
}
}
printf("----------------Closing client------------------ \n");
close(sockfd);
}
每个客户端都应该得到一个客户端发送到服务器的消息,就像聊天应用程序一样。
【问题讨论】:
-
与您的问题无关,但您应该知道在输入流中调用
fflush(如stdin)是未定义。如果您希望代码可移植,请不要这样做。您还应该永远使用gets,它很危险,甚至已从 C 标准中删除。我还建议您使用例如STDIN_FILENO而不是 "magic number"0。 -
@Joachim 非常感谢!!我应该使用
fgets而不是gets吗? -
是的,这是推荐的替代品。请注意,
fgets会将换行符添加到缓冲区中(如果合适的话),因此您必须检查并删除它(通过将其替换为字符串终止符)。 -
我认为它必须停止在第三个 if 因为gets()而在while循环中阻塞......所以它不能像实时聊天应用程序那样读取,不是吗?
标签: c sockets select tcp network-programming