为什么 TCP 服务器收到损坏的消息?

Why is TCP server receiving corrupted messages?

我正在尝试在同一端口上设置 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));
        }
    }

好了,问题来了:

 connfd = accept(tcp_listenfd, (struct sockaddr*)&cli_addr, &len);
 do {
    numbytes=recv(tcp_listenfd, tcp_buff, sizeof(tcp_buff), 0);

在您的 recv() 调用中,当您应该传入 connfd 时,您传入了 tcp_listenfd。 (您还应该检查所有函数调用的 return 值以确保函数成功,并在函数调用失败时采取适当的操作(例如通过 perror() 打印错误消息)。请参阅每个函数的手册页,了解有关 return-values 构成该函数成功与失败的详细信息)