首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >立即从套接字接收TCP有效负载(逐个数据包)

立即从套接字接收TCP有效负载(逐个数据包)
EN

Stack Overflow用户
提问于 2011-09-15 05:27:15
回答 4查看 3.7K关注 0票数 4

我如何从一个开放的网络套接字接收数据(字节流)?我希望在数据到达时立即从套接字中读取数据(只要数据包到达机器)。

似乎当我在套接字上执行一个read() (或recv())调用时,我得到的是10,000+字节的整个TCP消息。相反,我希望接收第一个TCP数据段有效负载,处理它,然后继续下一个,依此类推。

注意--我不想要原始数据包。仅TCP段数据有效负载。

还要注意-本质上,我希望通过在数据到达时立即处理数据来最小化延迟,而不是等待整个TCP消息在TCP层中累积。

任何想法都将不胜感激,谢谢!

EN

回答 4

Stack Overflow用户

发布于 2011-09-15 06:30:40

也许我误解了你的问题(例如,我不太明白‘不想要原始数据包,只需要TCP有效负载’),但是一个简单的原始套接字(IPPROTO_TCP)连接,然后用recv()嗅探就可以了。您可以在recv()中以参数的形式指定最大缓冲区大小,但是当TCP负载到来时,它将被报告回来--不需要等待缓冲区填满。以下是打印TCP数据包的一些代码摘录:

代码语言:javascript
复制
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#include // your header to print out bytes and error messages here

int main(void) {
    int i, recv_length, sockfd;
    u_char buffer[9000];

    if ((sockfd = socket(PF_INET, SOCK_RAW, IPPROTO_TCP)) == -1)
        // your error message here

    for(i=0; i < 3; i++) {
        recv_length = recv(sockfd, buffer, 8000, 0);
        printf("Got a %d byte packet\n", recv_length);
        // your routine to print out bytes here
    }
}

如果这不是你所关心的,请澄清。

编辑:根据我所听到和读到的,使用库pcap (libcap)比使用原始套接字(更可靠,功能非常强大-由编写tcpdump的人编写)更好。然而,我自己仍然在学习pcap,到目前为止,我正在努力让它在无线设备上正常工作。但是,如果你需要一个持续的基础,也可以研究一下这一点。

票数 2
EN

Stack Overflow用户

发布于 2011-09-15 18:00:44

TCP没有“消息”。它只是一个字节流。套接字API不允许您访问单个IP数据包或TCP数据段所承载的数据。

但是,如果您希望在操作系统能够提供某些数据时立即读取数据,则可以

  1. 将套接字设置为非阻塞模式,方法是使用带有I/O通知服务的套接字descriptor.
  2. Register套接字描述符的fcntl()调用,如select()、poll()、epoll。
  3. 等待此服务上的I/O事件。
  4. 当指示套接字已准备好读取时,您将从中读取-无论此时有多少数据可用,您都将从中读取。(并处理read/recv返回-1和errno设置为EWOULDBLOCK的情况)
票数 1
EN

Stack Overflow用户

发布于 2011-09-15 17:46:15

数据一到,你就应该马上得到它。没有“整个TCP消息”这样的东西。每次对readrecv的调用都应该提供与当时接收到的一样多的有序字节。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7423192

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档