Winsock 发送附加数据
我正在用 winsock 用 c++ 编写一个小型客户端/服务器应用程序,但我无法解释正在发生的一些事情。 我编写了两个基本函数,通过 TCP 连接发送/接收所有数据。
bool sending(SOCKET source, char* buff, int size, int flags = 0)
{
int sent = 0;
int totalst = 0;
int total = size;
while(totalst != total)
{
sent = send(source, buff+totalst, size-totalst, flags);
if(sent > 0)
{
totalst += sent;
}
if(sent == SOCKET_ERROR)
{
return false;
}
}
return true;
}
bool receive(SOCKET source, char* buff, int size, int flags = 0)
{
int rec = 0;
int totalrc = 0;
int total = size;
while(totalrc != total)
{
rec = recv(source, buff+totalrc, size-totalrc, flags);
if(rec > 0)
{
totalrc += rec;
}
if(rec == SOCKET_ERROR)
{
return false;
}
}
return true;
}
服务器发送一个整数,其中包含跟随它的数据块的大小。在我的情况下,数据块的大小不应该更改后,它应该始终为 92600 字节,但有时客户端会收到 92604 字节。奇怪的是,如果我在发送块大小和块本身(带有睡眠)后让服务器等待,它总是发送我期望的内容。
int i=0;
while(i < 100)
{
i++;
dat = getData();
len = sizeof(dat);
sending(source, (char*)&len, sizeof(len));
sending(source, dat, len);
Sleep(200);
}
客户端是否会因为滞后而收到不正确的字节值? 有什么办法可以解决这个问题吗? 任何帮助表示赞赏!
I'm writing a small client/server application in c++ with winsock and I can't explain a few things that are happening..
I wrote 2 basic functions that send/receive all the data through a TCP connection..
bool sending(SOCKET source, char* buff, int size, int flags = 0)
{
int sent = 0;
int totalst = 0;
int total = size;
while(totalst != total)
{
sent = send(source, buff+totalst, size-totalst, flags);
if(sent > 0)
{
totalst += sent;
}
if(sent == SOCKET_ERROR)
{
return false;
}
}
return true;
}
bool receive(SOCKET source, char* buff, int size, int flags = 0)
{
int rec = 0;
int totalrc = 0;
int total = size;
while(totalrc != total)
{
rec = recv(source, buff+totalrc, size-totalrc, flags);
if(rec > 0)
{
totalrc += rec;
}
if(rec == SOCKET_ERROR)
{
return false;
}
}
return true;
}
The server sends out an integer that contains the size of the data block that will follow it.. This size of the data block in my case shouldn't change, it should always be 92600 bytes, but sometimes the client receives 92604 bytes instead. The odd thing is that if I make the server wait after sending the bock size and the block itself(with Sleep) it always sends what I would expect..
int i=0;
while(i < 100)
{
i++;
dat = getData();
len = sizeof(dat);
sending(source, (char*)&len, sizeof(len));
sending(source, dat, len);
Sleep(200);
}
Can it bee that the client receives the incorrect value of bytes because of lag ?
Is there any way of fixing this?
Any help is appreciated!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

发布评论
评论(2)
您的发送和接收功能都有错误。
您正确地跟踪发送/接收的总字节数,以便正确退出循环,但您忘记在后续调用发送/接收中调整“buff”和“size”的值。如果要发送的缓冲区必须通过多次调用发送来传输,则您将发送错误的数据。
同样,如果需要多次调用“recv”,您将覆盖在缓冲区开头复制的数据。
它应该是:
sent = send(source, buff+totalst, size-totalst, 0);
对于recv情况也是如此:
rec = recv(source, buff + totalrc, size-totalrc, 0);
我不确定这是否会导致您的问题,但我有一种感觉,当todda指出的情况是正确的时,那么您的数据流就会被这个错误损坏。
有道理吗?另外,您应该准备好处理 recv() 将返回 0 的情况。
我希望这会有所帮助。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
考虑这个例子:
您期望这里发生什么?
实际上,四个
send
发送的数据可以被一个recv
接收。您不能保证,如果您对send
进行n
次调用,就会对recv
进行n
次调用接收所有数据。正如 nos 所评论的,TCP 不实现消息边界。这就是你在应用层的工作。 Winsock 不会发送额外的数据,而是您发送。
Consider this example:
What do you expect to happen here?
In practice, the data sent by four
send
's can be received into onerecv
. You don't have any guarantee that if you maken
calls tosend
you will maken
calls torecv
to recieve all the data.As nos has commented, TCP doesn't implement message boundaries. That's your job, on the application layer. Winsock doesn't send additional data, you do.