Socket recv()函数获取null消息

时间:2017-12-09 15:57:33

标签: c sockets

我有关于recv()函数的问题 当我首先将第一条消息(例如:hi)发送到服务器时,服务器会将相同的消息发送回客户端 我再次发送(例如:hi2),我会收到一条空信息 但我一直在发信息,也许我再次发了两次。我收到了第二封邮件。

我希望结果是客户端发送到服务器,客户端立即收到正确的消息。

我该如何解决这个问题?

我的客户:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>


int main(int argc , char *argv[])
{
    int sockFD = 0;
    sockFD = socket(AF_INET , SOCK_STREAM , 0);

    if (sockFD == -1){
        printf("Fail to create a socket.");
    }

    struct sockaddr_in info;
    bzero(&info,sizeof(info));
    info.sin_family = PF_INET;
    info.sin_addr.s_addr = inet_addr("127.0.0.1");
    info.sin_port = htons(8080);


    if(connect(sockFD,(struct sockaddr *)&info,sizeof(info)) == -1){
        perror("connect()");
    }


    char receiveMessage[100] = {};
    memset(receiveMessage, 0, sizeof(receiveMessage));

    char* input;
    while(scanf("%s", input) == 1){
        if(strcmp("exit", input) == 0){
            break;
        }

        if(send(sockFD, input, sizeof(input), 0) < 0){
            perror("send()");
        }

        if(recv(sockFD, receiveMessage, sizeof(receiveMessage), 0) < 0){
            perror("recv()");
        }

        printf("Server: %s\n",receiveMessage);
    }
    printf("close Socket\n");
    close(sockFD);
    return 0;
}

我的服务器:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>

int main()
{
    int sockFD = 0, clientSockFD= 0;
    char inputBuffer[256] = {};
    //char outputBuffer[256] = {};
    fd_set masterFD;
    fd_set readFD;
    int fdMax;

    // create socket
    sockFD = socket(AF_INET, SOCK_STREAM, 0);
    if(sockFD == -1){
        perror("socket()");
        exit(0);
    }

    struct sockaddr_in serverInfo, clientInfo;
    int addrLen = sizeof(clientInfo);
    bzero(&serverInfo, sizeof(serverInfo));

    serverInfo.sin_family = PF_INET;
    serverInfo.sin_addr.s_addr = INADDR_ANY;
    serverInfo.sin_port = htons(8080);

    // bind port
    if(bind(sockFD, (struct sockaddr *)&serverInfo, sizeof(serverInfo))){
        perror("bind()");
    }
    // listen
    if(listen(sockFD, 10)){
        perror("listen()");
    }

    FD_SET(sockFD, &masterFD);
    fdMax = sockFD;

    while(1){
        readFD = masterFD;

        if(select(fdMax + 1, &readFD, NULL, NULL, NULL) == -1){
            perror("select()");
            exit(0);
        }

        for(int i = 0; i <= fdMax; i++){
            if(FD_ISSET(i, &readFD)){
                if(i == sockFD){
                    if((clientSockFD = accept(sockFD, (struct sockaddr *)&clientInfo, &addrLen)) < 0){
                        perror("accept()");
                    }

                    FD_SET(clientSockFD, &masterFD);
                    if(clientSockFD > fdMax){
                        fdMax = clientSockFD;
                    }

                    printf("selectserver: new connection\n");
                }
                else{
                    int recvStatus = recv(i, inputBuffer, sizeof(inputBuffer), 0);
                    if(recvStatus <= 0){
                        if(recvStatus < 0){perror("recv()");}
                        else if(recvStatus = 0){printf("colse connected");}

                        close(i);
                        FD_CLR(i, &masterFD);
                    }
                    else{
                        printf("client: %s\n", inputBuffer);
                        send(i, inputBuffer, sizeof(inputBuffer), 0);
                    }
                }
            }
        }
    }


    return 0;
}

1 个答案:

答案 0 :(得分:0)

更改

 send(i, inputBuffer, sizeof(inputBuffer), 0);

分为:

 send(i, inputBuffer,recvStatus , 0);

原因:您发送的是一个完整的缓冲区,只包含几个预期的字符,但是使用NUL填充(最大为256)(或者以前的调用中的垃圾是垃圾))

recv()read()会返回收到的字符数。 (或EOF为0,错误为-1(其中一些可以处理,例如:EAGAIN,EINTR))