c++中,Send()函数发送额外的字节

C++ , Send() function sends extra bytes

本文关键字:字节 函数 Send c++      更新时间:2023-10-16

我在使用Winsock2包装器类(客户机-服务器)时遇到了麻烦,经过无数个小时的挠头,我决定如果我问一下你的意见会更好。

更具体地说,问题是每次我使用Send()函数时,客户端和服务器(并不总是!)都会发送一个或两个额外的字节!

例如,我使用SendBytes("Hello")和Recv函数返回"Hello•"与'•'或其他随机字符在字符数组的末尾。

    //main.cpp (Client)
    #include "Socket.h"
    int main() 
    {
        NetworkService::Client cService = NetworkService::Client();
        int res = cService.Initialize("127.0.0.1","20248");
        if(res == 0){
            int local = cService.SendBytes("Hello!");
            printf("Bytes Sent: %ldn", local);
            cService.Shutdown();
            char* temp = cService.Recv();
            printf("String Recieved: %s  - Size: %d",temp,strlen(temp));
            printf("nSTRLEN: %d",strlen("X5"));
        }
        else{
            cService.Clean();
        }
        cService.Close();
        while(!kbhit());
        return 0;
    }

当然,服务器发送字符串"X5",客户端打印字符串…

//The result with "X5" as the dummy text:  
String Recieved: X5? - Size: 3 //Notice the extra '?' character  
STRLEN: 2

发送//接收函数

    int NetworkService::Client::SendBytes(char* lData){
            int local = send( ConnectSocket, lData, (int)strlen(lData), 0 );
            if (local == SOCKET_ERROR) {
                Close();
                return WSAGetLastError();
            }
            return local;
    }
    char* NetworkService::Client::Recv(){
        recv(ConnectSocket, recvbuf , recvbuflen, 0);
        return recvbuf;
    }

希望能得到帮助^_^。

不好意思,但是

 int local;
 (...)
 return (int*)local;

你想达到什么目标?你的代码有很多严重的问题

这不是通过网络发送数据的方式。错误太多了。

如果你想通过网络发送以空结尾的字符串:

int local = send( ConnectSocket, lData, (int)strlen(lData), 0 );
正如大家所说,你实际上并没有发送空终止符。如果你在长度上加1,你就会发送它。此外,对于长字符串,send()函数不能保证一次发送整个字符串。你必须检查一下,然后重新发送缺失的部分。
recv(ConnectSocket, recvbuf , recvbuflen, 0);

你没有检查返回值,所以你不能知道接收到的字符串的长度。由于不发送空字节,因此接收到的数据不是以空结束的。此外,如果空结束符是您发送的更多数据的唯一分隔符,则必须逐个字节读取(效率不高),以免错过空结束符以知道何时结束。另一种选择是制定自己的缓冲方案(这样下一次读取将部分返回前一次读取的结果),或者更改协议以事先知道传输数据的长度。同样,关于send函数的部分读取的注释也适用于这里。

返回静态/全局缓冲区并不是好代码的标志

你没有真的检查recv的返回值

有一个do-while,但它不做任何事情。即使recv失败,您也可以从函数返回而没有适当的错误处理,但是您永远不会知道它。

也不发送终止,这不是必要的坏,取决于你想做什么,例如,你可以在接收后添加。