【发布时间】:2019-10-01 13:37:42
【问题描述】:
我正在尝试在同一端口上设置 TCP/UDP 服务器托管。
UDP 部分工作正常,但 TCP 部分无法正确接收消息。
我尝试使用 netcat 对其进行测试,例如。当我发送“TCP y u do dis”时,它会输出类似“D(”的内容并继续在 do while 循环中旋转。
//Creating TCP listen socket
tcp_listenfd=socket(AF_INET, SOCK_STREAM, 0);
bzero(&tcp_servaddr, sizeof(tcp_servaddr));
tcp_servaddr.sin_family=AF_INET;
tcp_servaddr.sin_port=htons(atoi(tcp_port));
tcp_servaddr.sin_addr.s_addr=htonl(INADDR_ANY);
//Binding TCP socket
setsockopt(tcp_listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
bind(tcp_listenfd,(struct sockaddr*)&tcp_servaddr,sizeof(tcp_servaddr));
listen(tcp_listenfd, 10);
//Creating UDP listen socket
udp_listenfd=socket(AF_INET, SOCK_DGRAM, 0);
bzero(&udp_servaddr, sizeof(udp_servaddr));
udp_servaddr.sin_family=AF_INET;
udp_servaddr.sin_port=htons(atoi(udp_port));
udp_servaddr.sin_addr.s_addr=htonl(INADDR_ANY);
//Binding UDP listen socket
bind(udp_listenfd, (struct sockaddr*)&udp_servaddr, sizeof(udp_servaddr));
//Clear descriptor set
FD_ZERO(&rset);
//Max file descriptor
maxfd = max(tcp_listenfd, udp_listenfd)+1;
while(1){
// set listenfd and udpfd in readset
FD_SET(tcp_listenfd, &rset);
FD_SET(udp_listenfd, &rset);
nready = select(maxfd, &rset, NULL, NULL, NULL);
if (FD_ISSET(tcp_listenfd, &rset)) {
printf("TCP ready!\n");
len=sizeof(cli_addr);
connfd = accept(tcp_listenfd, (struct sockaddr*)&cli_addr, &len);
do {
numbytes=recv(tcp_listenfd, tcp_buff, sizeof(tcp_buff), 0);
printf("Received message: %s\n", tcp_buff);
}while(strcmp(tcp_buff, "HELLO\n")!=0);
send(tcp_listenfd, payload, strlen(payload)+1, 0);
close(connfd);
bzero(&cli_addr, sizeof(cli_addr));
}
if(FD_ISSET(udp_listenfd, &rset)){
printf("UDP ready!\n");
len=sizeof(cli_addr);
do{
recvfrom(udp_listenfd, udp_buff, 1024, 0,(struct sockaddr *)&cli_addr, &len);
}while(strcmp(udp_buff, "HELLO\n")!=0);
sendto(udp_listenfd, payload, strlen(payload)+1, 0, (struct sockaddr *)&cli_addr, len);
close(udp_listenfd);
bzero(&cli_addr, sizeof(cli_addr));
}
}
【问题讨论】:
-
你打印出
recv()返回的值了吗?由于 TCP 是一个流协议,即使成功,它也可以是 1 到sizeof(tcp_buff)之间的任何值,特别是任何给定的recv()调用写入缓冲区的字节数不能保证与传递给发送程序中任何较早的send()调用的字节数。另请注意,printf("%s", [...])假定您传递给它的字符串将被 NUL/0 终止,这在recv()返回后可能不是这种情况,因为recv()在二进制级别上工作并且不遵循 C 字符串语义. -
recv() 的返回值为 -1。字符串是空终止的,我已经用其他程序 client.c 测试了它,它通过 TCP 发送空终止的字符串。
-
@user3104311 这还不够好。仔细阅读 Jeremy 的评论。
标签: c sockets tcp network-programming