首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >TCP套接字垃圾

TCP套接字垃圾
EN

Stack Overflow用户
提问于 2014-05-17 12:46:17
回答 2查看 2K关注 0票数 0

我有一个TCP协议服务器-客户端程序。

与许多人不同的是,我没有收到错误,因为我的send函数没有发送足够多的字节。我的问题是因为recv()函数捕获了许多奇怪的字符。我对它们进行了六进制转储,它们往往要么是负数(我猜长度大于4位),要么不是字母数字(总是出现的是\8 =◘)。

我使用的函数如下:

代码语言:javascript
复制
bool Socket::Send(char* msg){
    if ((send(sockfd, msg, strlen(msg), 0)) == SOCKET_ERROR){
        Close();
        return false;
    }
    return true;
}

int Socket::Receive(char* msg, int maxlen){
    int recvResult;
    if ((recvResult = recv(sockfd, msg, maxlen, 0)) == SOCKET_ERROR){
        Close();
    }
    return recvResult;
}

我检查了一下,所有发送的东西都没问题。我的意思是,我把它写到一个文件,并检查它,它是好的。

还有什么是我应该考虑的吗?我做错了什么?

EN

回答 2

Stack Overflow用户

发布于 2014-05-17 12:56:33

与许多人不同的是,我没有收到错误,因为我的发送函数没有发送足够多的字节。

没有人会得到这个错误,因为它从来没有发生过,尽管,因为您没有检查它,所以您无法断言它没有发生。

我的问题是因为recv()函数捕获了许多奇怪的字符。

不是的。发生的情况是,recv()函数返回的字节数少于请求的字节数,这是因为没有指定它在非阻塞模式下传输超过一个字节或零字节。你必须循环,直到你读完所有你想要的数据。

而且,您必须注意不要使用接收缓冲区中未在最近的recv()调用中传输的字节,如其返回值所示。

你几乎肯定会打印整个缓冲区,所以你看到的是垃圾。它既没有被发送也没有被接收。

注意:如果recv()返回零,您应该关闭套接字。

票数 1
EN

Stack Overflow用户

发布于 2014-05-17 20:26:13

你说你有一个TCP协议,你拥有的不仅仅是一个TCP连接的协议。

为了实现一个协议,你需要发送更多的信息,recv()部分应该(必须)知道将要接收什么。

您需要在缓冲区长度之前发送一个终止字符,或者在缓冲区的末尾发送一个终止字符,这不应该是已发送消息的其余部分。像换行符(10)、回车符(13)和换行符(12)这样的字符是很好的候选者。

如果您决定使用终止字符,那么您应该一次读取(recv)一个字符,验证这是否是终止指示符。终止字符仅在发送代表文字的字符串时有用,未指明用于发送文件或图像或二进制字符串。

我已经修改了实现缓冲区指示器方法的长度的例程:

代码语言:javascript
复制
bool Socket::Sender(char* msg){
    // Send a string with the length (int) of it ahead
    int len = strlen(msg);
    int hLen = htonl(len); // put it in network byte order
    if (send(sockfd, (char *) &hLen, sizeof(int), 0) == sizeof(int) &&
        send(sockfd, msg, len, 0) == len) 
    {
        return true;
    }
    Close();
    return false;
}

int Socket::Receive(char* msg, int maxlen){
    int recvResult;
    int len;
    int offset;

    // receive a string with the length (int) of it first
    if (recv(sockfd, (char *) &len, sizeof(int), 0) == sizeof(int))
    {
        len=ntohl(len); // put in host byte order
        // Check there is enough space
        if (len > maxlen)
        {
            // the receive chars is bigger than maxlen, 
            // either receive as many as maxlen or return error
            len=maxlen;
            // Close();
            // return -1;
        }
        offset=0;
        // loop until len chars are received, no more no less
        while (offset < len) 
        {
            recvResult = recv(sockfd, (char *) &msg[offset], len-offset, 0);
            if (recvResult <= 0)
            {
                Close();
                return -1;
            }
            offset +=recvResult;
        }
        // Succeeded, return len
        return len;
    }
    Close();
    return -1;
}
票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23707673

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档