我有一个TCP协议服务器-客户端程序。
与许多人不同的是,我没有收到错误,因为我的send函数没有发送足够多的字节。我的问题是因为recv()函数捕获了许多奇怪的字符。我对它们进行了六进制转储,它们往往要么是负数(我猜长度大于4位),要么不是字母数字(总是出现的是\8 =◘)。
我使用的函数如下:
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;
}我检查了一下,所有发送的东西都没问题。我的意思是,我把它写到一个文件,并检查它,它是好的。
还有什么是我应该考虑的吗?我做错了什么?
发布于 2014-05-17 12:56:33
与许多人不同的是,我没有收到错误,因为我的发送函数没有发送足够多的字节。
没有人会得到这个错误,因为它从来没有发生过,尽管,因为您没有检查它,所以您无法断言它没有发生。
我的问题是因为recv()函数捕获了许多奇怪的字符。
不是的。发生的情况是,recv()函数返回的字节数少于请求的字节数,这是因为没有指定它在非阻塞模式下传输超过一个字节或零字节。你必须循环,直到你读完所有你想要的数据。
而且,您必须注意不要使用接收缓冲区中未在最近的recv()调用中传输的字节,如其返回值所示。
你几乎肯定会打印整个缓冲区,所以你看到的是垃圾。它既没有被发送也没有被接收。
注意:如果recv()返回零,您应该关闭套接字。
发布于 2014-05-17 20:26:13
你说你有一个TCP协议,你拥有的不仅仅是一个TCP连接的协议。
为了实现一个协议,你需要发送更多的信息,recv()部分应该(必须)知道将要接收什么。
您需要在缓冲区长度之前发送一个终止字符,或者在缓冲区的末尾发送一个终止字符,这不应该是已发送消息的其余部分。像换行符(10)、回车符(13)和换行符(12)这样的字符是很好的候选者。
如果您决定使用终止字符,那么您应该一次读取(recv)一个字符,验证这是否是终止指示符。终止字符仅在发送代表文字的字符串时有用,未指明用于发送文件或图像或二进制字符串。
我已经修改了实现缓冲区指示器方法的长度的例程:
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;
}https://stackoverflow.com/questions/23707673
复制相似问题