关于数据包和缓冲区大小的TCP套接字编程
TCP socket programming regarding the packet and buffer size
我知道TCP中没有数据包概念,因为它是一个流套接字,那么例如,如果我有一个2000字节的数据包,比如说2000‘a’,而我的默认缓冲区大小是1024,那么它应该发送两次,接收两次?
所以对于send()函数,
iResult = send(s, sendbuf, packet_size, 0);
对于第二个参数,我应该放什么?一个有1024字节mallocated的发送缓冲区字符指针或一个有2000字节的数据包字符指针,它会自动为我处理它吗?
对于recv()阻塞函数,我应该将缓冲区字符指针放在第二个参数还是数据包指针?
对于报头,我的朋友建议我添加4字节的报头来存储数据包信息,例如数据包的序列号和大小,如何实现?感谢
@乔治,谢谢!我还想问,如果我不进行部分写入处理,while循环中的发送速率非常快(没有睡眠),那么服务器端会出现错误/丢失吗?对于recv()
SOCKET newsfd;
bind(s, (struct sockaddr *)ReceiverSocket, sizeof(struct sockaddr_in));
if (strcmp(protocol, "tcp") == 0 || strcmp(protocol, "TCP") == 0){
listen(s, 1);
newsfd = accept(s, 0, 0);
}
//*** Create Update Display Thread
std::thread th(Function_packet_transmission_display, update_interval, (char*) "recv");
//*** Receive Data//*** Set Jitter
long time_old = 0, time_new = 0, time_start = 0;
long float jitter_new = 0, jitter_old = 0;
long long temp_accubyte = 0, temp_pktnum = 0; //testing
char *recvbuf = new char[buffer_size];
long long next_seq_num = 1; int retVal;
do{
if (strcmp(protocol, "tcp") == 0 || strcmp(protocol, "TCP") == 0){
retVal = recv(newsfd, recvbuf, packet_size, 0);
if ((retVal == SOCKET_ERROR) || (retVal == 0)){
printf("nreturn fail code:%in", WSAGetLastError());
closesocket(s);
WSACleanup();
lck.lock();
Ended = true;
lck.unlock();
return 0;
}
}
else if (strcmp(protocol, "udp") == 0 || strcmp(protocol, "UDP") == 0){
int fromlen = (int)sizeof(struct sockaddr_in);
retVal = recvfrom(s, recvbuf, packet_size, 0, (struct sockaddr *)ReceiverSocket, &fromlen);
}
//testing
temp_accubyte += retVal;
temp_pktnum++;//TEST
//printf("racc: %lld %lld - ", temp_accubyte, temp_pktnum);
//if (temp_pktnum==100000) printf("nReach 100000n", temp_accubyte, temp_pktnum);
if (timer == NULL){
timer = new ES_FlashTimer();
}
如果我有一个2000字节的数据包,比如说2000‘a’,
你没有。您有一条2000字节的消息。
我的默认缓冲区大小是1024
不太可能。这将是至少8192,可能成千上万的K
那么它应该发送两次
至少。
收到两次?
至少。
对于第二个参数,我应该放什么?
要发送的消息的大小:在本例中为2000。
发送带有1024字节错误分配的缓冲区字符指针
没有。
还是一个2000字节的数据包字符指针,它会自动为我处理它?
是的。
对于recv()阻塞函数,我应该将缓冲区字符指针放在第二个参数还是数据包指针?
我无法理解这一点,但您应该将接收到尽可能大的缓冲区中,并循环直到您获得整个消息。
对于报头,我的朋友建议我添加4字节的报头来存储数据包信息,例如数据包的序列号和大小,如何实现!
您并不真的需要序列号,但消息大小是个好主意。把它贴在信息的前面。不清楚这里的问题是什么。
您将需要像这里一样的sendall,并且(可能)需要编写类似的receivall
。这是sendall
(略有修改):
#include <sys/types.h>
#include <sys/socket.h>
int sendall(int s, char *buf, int *len)
{
int total = 0; // how many bytes we've sent
int bytesleft = *len; // how many we have left to send
int n = -1;
while(total < *len) {
n = send(s, buf+total, bytesleft, 0);
if (n <= 0) { break; }
total += n;
bytesleft -= n;
}
*len = total;
return (n<=0)?-1:0; // return -1 on failure, 0 on success
}
你可以在这里阅读如何处理信息框架,这正是你所需要的。
- C++ TCP 套接字通信 - 连接按预期工作,几秒钟后失败,没有收到新数据,read() 和 recv() 块
- C++ TCP 套接字 | 无法将"std::__cxx11::字符串"转换为"const
- ASIO 的 TCP 套接字::async_wait() 并在此之后关闭套接字
- Visual Studio(C++):如何使用TCP套接字发送多个值
- TCP套接字(客户端-服务器)recv()返回-1值
- C++中TCP套接字的recv函数
- 通过 TCP 套接字发送大型 base64 字符串
- 提升 ASIO TCP 套接字 1.70 不向后兼容
- 尝试连接到 TCP 套接字 (Linux) 时连接被拒绝
- 如何知道请求是否完全使用 TCP 套接字接收?
- Qt TCP 套接字 - 写入超过 15 个字节
- 同一提升 TCP 套接字对象上的多个连接
- 如何使用 recv 或 C++ 中的读取功能从 tcp 套接字读取大请求
- 如何<double>通过TCP套接字将CLI 列表^发送到本机C++?
- SOCAT,将TCP套接字转发到Unix套接字,将recvmsg()更改为read(),删除辅助数据
- 强制终止和重新生成 TCP 套接字应用程序时无法重用端口
- 通过 TCP 套接字发送结构 C++
- SIGPIPE C++确定哪个 TCP 套接字已断开连接
- 通过Qt-tcp套接字更改Qt-GUI
- C# 客户端到C++服务器 Tcp 套接字连接错误