WinSock 2.2 TCP/IPv4 send()总是返回发送的所有字节
WinSock 2.2 TCP/IPv4 send() always returns all bytes sent
WinSock 2.2 send()函数总是返回我想要它发送的所有字节!我连接到google.com端口80和发送随机的t
字母的数据。我甚至尝试发送多达1GB的t
,它仍然返回所有发送的字节。我希望它能和我一起返回多少字节,它可以装在一个数据包中,其余的将由while循环在实现中处理,但它永远不会进入while循环内部!
我使用TCP/IPv4套接字。我知道我的网速不够快,发送1GB的速度比我眨眼的速度还快。
这段代码显示了大多数重要的块。例如,省略了c字符串send调用的包装器,它调用了我所示的send。
调用测试代码
//prepare the long data string
int buffSize = 1 * 1000 * 1000 * 1000;
char *buff = new char[buffSize];
memset(buff, 't', buffSize);
buff[buffSize - 3] = 'n';
buff[buffSize - 2] = 'n';
buff[buffSize - 1] = ' ';
//send thee data
int bytesSent = socket->send(buff);
//verify all thee data is sent
CHECK(bytesSent == strlen(buff));
发送implementatian
int mySocket::send(const void *data, int length)
{
int bytesSent = ::send(socketDescriptor, (char*)data, length, 0);
if (bytesSent == SOCKET_ERROR) return -1;
while(bytesSent < length)
{
int sent = ::send(socketDescriptor, (char*)data + bytesSent, length - bytesSent, 0);
if (sent == SOCKET_ERROR) return bytesSent;
bytesSent += sent;
}
return bytesSent;
}
编辑1
因为它开始让人感到困惑这里是包装器
发送包装
int mySocket::send(const char * data_string)
{
return send(dataString, strlen(data_string));
}
编辑2
是一个完整的工作示例,您可以调试。它产生相同的结果,它只是立即报告发送的所有字节。
#include <WinSock2.h>
#include <WS2tcpip.h>
#include <stdio.h>
#pragma comment(lib, "ws2_32.lib")
class mySocket
{
public:
mySocket(SOCKET sockeDesc)
{
socketDescriptor = sockeDesc;
}
int mySocket::send(const void *data, int length)
{
int bytesSent = ::send(socketDescriptor, (char*)data, length, 0);
if (bytesSent == SOCKET_ERROR) return -1;
while (bytesSent < length)
{
int sent = ::send(socketDescriptor, (char*)data + bytesSent, length - bytesSent, 0);
if (sent == SOCKET_ERROR) return bytesSent;
bytesSent += sent;
}
return bytesSent;
}
int mySocket::send(const char * data_string)
{
return send(data_string, strlen(data_string));
}
private:
SOCKET socketDescriptor;
};
int main()
{
WSAData wsd;
if (WSAStartup(MAKEWORD(2, 2), &wsd) || wsd.wVersion != MAKEWORD(2, 2))
{
WSACleanup();
return 1;
}
//create ze socket
SOCKET socketDescriptor = socket(AF_INET, SOCK_STREAM, 0);
//look up socket info
addrinfo hints;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
addrinfo *res;
int errCode = getaddrinfo("google.com", "80", &hints, &res);
if (errCode) return 1;
//connect ze socket
int connectStatusCode = ::connect(socketDescriptor, res->ai_addr, res->ai_addrlen);
if (connectStatusCode == SOCKET_ERROR) return 1;
//create zeeeee socket!
mySocket *socket = new mySocket(socketDescriptor);
//prepare ze long data string
int buffSize = 1 * 1000 * 1000 * 1000;
char *buff = new char[buffSize];
memset(buff, 't', buffSize);
buff[buffSize - 3] = 'n';
buff[buffSize - 2] = 'n';
buff[buffSize - 1] = ' ';
//send ze data
int bytesSent = socket->send(buff);
//verify all ze data is sent
bool success = (bytesSent == strlen(buff));
printf("requested bytes = %insent bytes = t %i", strlen(buff), bytesSent);
printf("nnsuccess = %s", success ? "true" : "false");
closesocket(socketDescriptor);
delete socket;
freeaddrinfo(res);
WSACleanup();
getchar();
return 0;
}
编辑3
https://msdn.microsoft.com/en-us/library/windows/desktop/ms740506 (v = vs.85) . aspx
评论
…
发送函数的成功完成没有指示数据已成功地传递和接收到接收方。此函数仅指示数据成功 .
但是@Karsten Koop指出了有关相关行为的类似问题:Windows中套接字发送缓冲区的大小是多少?我不太明白上面写的是什么。但是我得到的是,它说函数只是写入缓冲区并返回"发送"的字节。但这不仅意味着它不能保证接收方收到了数据(微软说),而且意味着它实际上根本没有发送……只是在缓冲中。是我遗漏了什么,还是微软误导了自己的行为?
有多种类型的套接字:Winsock支持多种协议。
- https://msdn.microsoft.com/en-us/library/windows/desktop/ms740506 (v = vs.85) . aspx
仅仅因为socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)
的当前实现通常似乎阻塞直到所有数据发送,并不意味着其他套接字类型也会阻塞。
此外,如果进程被中断,例如网络中断,或者套接字从另一端或被另一个线程关闭,send
可能会发送少于满缓冲区的数据。
此外,Winsock API被设计为与BSD和Posix套接字API兼容,并且在这些平台上,如果在调用期间接收到信号,send
通常会返回错误EINTR
。(在Unixland中,大多数阻塞调用都可以使用errno==EINTR
返回,这就是如何解决单线程系统上处理外部事件的问题)。
- 如何使用Crypto++并为RSA返回可打印的字节/字符数组
- C++/CX 如何从 IRandomAccessStream^ 转换为字节并返回.(UWP)
- 为什么 sys 套接字 recv 函数不填充数据但返回字节长度?
- C++ 从函数返回无符号字节
- 裸__declspec上的 memcpy 返回意外的字节
- InternetReadFile 填充缓冲区,但返回零字节读取
- 如果send()返回x字节,则recv()在一个呼叫中获取相同数量的字节
- ::运算符 delete(指针) 返回释放的字节大小
- 函数返回的 gsl::span 具有错误的字节
- 如何迫使新操作员返回的指针将是32字节对齐
- 返回字节数组或将数组传递到函数中
- crypto++将密钥保存到字节队列并返回到密钥
- mbtowc在osx上总是返回一个字节
- C 我应该如何返回字节数组
- 如何在C++中创建一个返回字节数组的函数?Arduino项目
- 如果在 main 中使用字符串,为什么 CRT 会返回 8 字节泄漏
- TCP Recv使用select()返回1字节读取
- 如何在Crypto++中返回字节值
- Microsoft psapi方法是否使用十进制或二进制表示法返回字节?
- 函数接受两个参数,一个字节和一个位字段,并返回字节中字段的值