我使用tcpdump从客户端捕获数据包,每个数据包都是分段到最大1448字节的数据,但是head只有5字节,为什么我可以成功读取head,但是下面的data recv()操作又会返回ee?当数据已经到达recv缓冲区时,recv是否可能返回EAGAIN?在我看来,我可以读取前5个字节,所以必须有更多的数据在recv缓冲区读取。
可能与TCP/IP协议栈中的组装过程有关。代码如下所示,每个pdu recv,需要10次或更多的重试,也许成功。
...
#define HDR_LEN 5
n = epoll(epfd, events, 1000, -1)
for(i =0; i < n; i++)
{
uint8 pHdr[HDR_LEN] = {0};
uint16 pdulen = 0, offset =0;
infd = events[i].fd;
nRead = recv(infd, pHdr, HDR_LEN); // read the data head first
pdulen = ntohs(*(uint16 *)(pHdr+2)); // get the pdu len from the head
uint8 *pbuf = malloc(pdulen+HDR_LEN);
memcpy(pbuf, pHdr, HDR_LEN); // move the head to buf
while(offset != pdulen) // then read the pdu data
{
nRead = recv(infd, pbuf+HDR_LEN+offset, pdulen-offset);
if (nRead <=0)
{
if (nRead == -1 && errno == EAGAIN) // resource temporarily unavailable
{
if (retry < 5)
{
usleep(500);
retry++;
continue;
}
else
break; // already try 5 times, should always continue?
}
else
break;
}
else
{
offset += nRead;
retry = 0;
}
}
if (offset == pdulen)
process(pbuf, pdulen+HDR_LEN); // process the complete data
...
}
...
epoll
将告诉您是否可以recv
而不阻塞。如果recv
使用了套接字的所有数据,那么下一个recv
将阻塞,直到有更多的数据,或者返回EAGAIN(如果非阻塞套接字)。
一个常见的模式是:
select/poll/epoll
检测何时可以读取套接字。recv
一次,并将接收到的数据追加到缓冲区。选择/poll/epoll
告诉您何时可以阅读更多内容。我正在实现一个UNIX域套接字进程间通信代码,在试图从套接字读取时,我随机地碰到了这个错误--“errno 11:资源暂时不可用”。我使用MSG_PEEK从套接字读取字节数,并为接收缓冲区分配字节数,并读取实际数据。 套接字是一个阻塞套接字,我没有任何非阻塞的代码(总之,接受/读/写)。在阻塞套接字读取中,有什么可能导致这种情况的指针吗?在MSG_PEEK的手册页中,当socket标记为非阻塞时,
创建套接字 使其非阻塞 呼叫连接 按预期返回-1和errno EINPROGRESS 调用select 返回>0,因此已建立连接 再次阻塞套接字 此部件的代码如下: 那还行。但是我有一个循环,在这个循环中我调用了一个函数,该函数检查是否收到了要读取的新数据包:
我正在编写一个简单的TCP客户端和服务器Perl脚本。到现在为止,我使用wireshark验证了三路TCP握手,并且建立了连接。但当我尝试发送或恢复数据时,什么也不会发生。 1)客户端和服务器之间的主要区别只是服务器增加了一个LISTEN参数,使它能够侦听传入的连接? 2)在recv和显示数据之间是否缺少任何步骤? 3)当程序第一次执行while循环时,难道不应该至少发送硬编码字符串“$respo
假定套接字处于阻塞模式
我正在使用TCP/IP套接字,我已经读过函数。因此,每当对等体断开连接时,recv按照文档返回0,但在windows上它不返回零,而是返回-1,并且中的值是我无法理解它为什么这样做。同样的代码在Linux中运行得非常好。
我想用pywebkitgtk捕获网页。我已经在那台机器上安装了X org服务器,除了一些例外情况外,还启动了X服务器,但是X服务器正在运行。问题是我不能从X unix套接字中读取任何数据,它是path=@“/tmp/.x11-unix/x0”的PF_FILE类型,recvfrom正在抛出EAGAIN(资源暂时不可用)错误,对该套接字的轮询经常超时,没有任何数据,下面是跟踪日志,在其中我们可以找到成