RECV缓冲区空,但返回值> 1 [英] RECV buffer empty, but returns a value > 1

查看:164
本文介绍了RECV缓冲区空,但返回值> 1的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图做一个简单的服务器,以便两个客户端可以相互通信。主服务器code接受两个客户连接,然后派生关闭使用execl的生成两个客户端之间的个人服务器,使得主服务器可以继续寻找新的连接的处理。一切似乎直到个人服务器尝试联系客户,他们都收到乱码,如果有谁知道这是什么原因,请让我知道正常工作。

接受两个客户端后,主服务器:

 如果(叉()== 0){
        关闭(听众);
        INT为nbytes;
        字符* playerOne [20];
        字符* playerTwo [20];        //创建一个字符串来保存execl的文件描述符信息
        焦炭connAscii [的sizeof(INT)];
        焦炭connAscii2 [的sizeof(INT)];
        的snprintf(connAscii,sizeof的(康涅狄格州),%D,康恩);
        的snprintf(connAscii2,sizeof的(CONN2),%D,CONN2);
        fprintf中(标准错误,内部康恩:%D,asciiConn:%S,backToInt:%d个\\ N的,康涅狄格州,connAscii,与atoi(con​​nAscii));
        字符* ARGF [2];
        ARGF [0] = connAscii;
        ARGF [1] = connAscii2;
        fprintf中(STDERR,也就是说%s和%s \\ n,辅助创收基金[0],辅助创收基金[1]);        //发送手柄请求连接1
        为nbytes =送(康涅狄格州的handleRequest,sizeof的(的handleRequest),0);
        如果(为nbytes == -1){
            PERROR(发送);
            出口(1);
        }
        //从连接1接收手柄
        为nbytes =的recv(康恩,playerOne,20,0);
        如果(为nbytes == -1){
            PERROR(RECV);
            出口(1);
        }
        //发送请求手柄2个连接
        为nbytes =送(CONN2,的handleRequest,sizeof的(的handleRequest),0);
        如果(为nbytes == -1){
            PERROR(发送);
            出口(1);
        }
        //从连接2接收手柄
        为nbytes =的recv(CONN2,playerTwo,20,0);
        如果(为nbytes == -1){
            PERROR(RECV);
            出口(1);
        }
        //发送手柄连接2连接1
        为nbytes =送(康涅狄格州,playerTwo,sizeof的(playerTwo),0);
        如果(为nbytes == -1){
            PERROR(发送);
            出口(1);
        }
        //发送手柄连接1连接2
        为nbytes =送(CONN2,playerOne,sizeof的(playerOne),0);
        如果(为nbytes == -1){
            PERROR(发送);
            出口(1);
        }        //传递文件描述符privateServer
        EXECL(privateServer,privateServer,connAscii,connAscii2,(字符*)0);
}

个人服务器通过调用execl的:

 字符迎接[] = {你好选手,请等待匹配的设置。};
INT主(INT ARGC,CHAR *的argv []){
    INT CONN1 =的atoi(ARGV [1]);
    INT CONN2 =的atoi(argv的[2]);
    INT发送;
    fprintf中(标准错误,试图用%d个\\ n连接,CONN1);
    发送=送(CONN1,打招呼,sizeof的(打招呼),0);
    如果(发送== -1){
        PERROR(发送);
        出口(1);
    }    发送=送(CONN2,打招呼,sizeof的(迎接),0);
    如果(发送== -1){
        PERROR(发送);
        出口(1);
    }
    fprintf中(标准错误,希望他们得到了\\ n);
    返回0;
    }

客户端:读取由乱码字符结果recv的BUFF char和打印整个缓冲区不显示任何东西,但的numBytes == 61

 的char * BUFF =(字符*)malloc的(100);
memset的(安培;抛光轮[0],0,sizeof的(浅黄色));
的numBytes =的recv(的sockfd,BUFF,99,0); //应该从专用服务器
如果(==的numBytes -1){
        PERROR(RECV);
        出口(1);
    }
BUFF [的numBytes] ='\\ 0';
INT I;
对于(i = 0; I<的numBytes;我++){
    fprintf中(标准错误,%C,BUFF [I]);
}
的printf(从比赛服务器:%* S(%d字节)\\ n,的numBytes,浅黄色,的numBytes);


解决方案

有几个误区:

 的char * playerOne [20];
字符* playerTwo [20];

您想字符数组,而不是指针数组以字符

更改

 字符playerOne [20];
炭playerTwo [20];

在这里:

 的char * BUFF =(字符*)malloc的(100);
memset的(安培;抛光轮[0],0,sizeof的(浅黄色));

的sizeof(BUFF)是一个指针的大小字符,更改为

  memset的(安培;迷[0],0,100);

正如@ user3629249指出,不要用幻数100一样,而不是

 的#define MAX_BUFF 100
字符* BUFF = malloc的(MAX_BUFF);
memset的(安培;抛光轮[0],0,MAX_BUFF);

但没有必要 memset的如果你是空的结束串。

I am attempting to make a simple server so that two clients can communicate with each other. The main server code accepts the two client connections and then forks off a process that uses execl to generate a personal server between the two clients so that the main server can continue looking for new connections. Everything seems to work correctly until the personal server attempts to contact the clients and they both receive gibberish, if anyone knows what could cause this please let me know.

Main server after accepting two clients:

if(fork() == 0){
        close(listener);
        int nBytes;
        char* playerOne[20];
        char* playerTwo[20];

        //Creates strings to hold file descriptor information for execl
        char connAscii[sizeof(int)];
        char connAscii2[sizeof(int)];
        snprintf(connAscii,sizeof(conn), "%d", conn);
        snprintf(connAscii2,sizeof(conn2), "%d", conn2);
        fprintf(stderr, "Int conn: %d, asciiConn: %s, backToInt: %d\n", conn, connAscii, atoi(connAscii));
        char *argf[2];
        argf[0] = connAscii; 
        argf[1] = connAscii2;
        fprintf(stderr, "that is to say %s and %s\n", argf[0], argf[1]);

        //Send Handle Request to Connection 1
        nBytes = send(conn, handleRequest, sizeof(handleRequest),0);
        if(nBytes == -1){
            perror("send");
            exit(1);
        }
        //Receive Handle from Connection 1
        nBytes = recv(conn, playerOne, 20, 0);
        if(nBytes == -1){
            perror("recv");
            exit(1);
        }
        //Send Handle Request to Connection 2
        nBytes = send(conn2, handleRequest, sizeof(handleRequest),0);
        if(nBytes == -1){
            perror("send");
            exit(1);
        }
        //Receive Handle from Connection 2
        nBytes = recv(conn2, playerTwo, 20, 0);
        if(nBytes == -1){
            perror("recv");
            exit(1);
        }
        //Send Handle for Connection 2 to Connection 1
        nBytes = send(conn, playerTwo, sizeof(playerTwo),0);
        if(nBytes == -1){
            perror("send");
            exit(1);
        }
        //Send Handle for Connection 1 to Connection 2
        nBytes = send(conn2, playerOne, sizeof(playerOne),0);
        if(nBytes == -1){
            perror("send");
            exit(1);
        }

        //Passes file descriptors to privateServer
        execl("privateServer","privateServer", connAscii, connAscii2, (char *)0); 
}

Personal server invoked by execl:

char greet[] = {"Hello players, please wait for match setup."};
int main(int argc, char *argv[]) {
    int conn1 = atoi(argv[1]);
    int conn2 = atoi(argv[2]);
    int sent;
    fprintf(stderr, "Attempting connection with %d\n", conn1);
    sent = send(conn1, greet,sizeof(greet),0);
    if(sent == -1){
        perror("send");
        exit(1);
    }

    sent = send(conn2, greet,sizeof(greet),0);
    if(sent == -1){
        perror("send");
        exit(1);
    }
    fprintf(stderr,"Hopefully they got it\n");
    return 0;
    }

Clients: Reading the recv buff char by char results in gibberish and printing the entire buffer doesn't show anything, but numbytes == 61.

char *buff = (char*)malloc(100);
memset(&buff[0],0,sizeof(buff));
numbytes = recv(sockfd, buff, 99, 0);  //should be from private server
if (numbytes == -1) {
        perror("recv");
        exit(1);
    }
buff[numbytes] = '\0';
int i;
for(i = 0; i < numbytes; i++){
    fprintf(stderr, "%c", buff[i]);
}
printf("From match server: %.*s (%d bytes)\n", numbytes, buff, numbytes);   

解决方案

There are several errors:

char* playerOne[20];
char* playerTwo[20];

You want an array of chars, not an array of pointers to chars

change to

char playerOne[20];
char playerTwo[20];

And here:

char *buff = (char*)malloc(100);
memset(&buff[0],0,sizeof(buff));

sizeof(buff) is the size of a pointer to char, change to

memset(&buff[0],0,100);

As pointed out by @user3629249, don't use magic numbers like 100, instead

#define MAX_BUFF 100
char *buff = malloc(MAX_BUFF);
memset(&buff[0],0,MAX_BUFF);

But there is no need to memset if you are null-terminating the string.

这篇关于RECV缓冲区空,但返回值&GT; 1的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆