Tag: 套接字

http服务器响应(套接字)的标头和内容之间不同

我想知道,有没有可能找出响应Stream中标题结束的位置? 问题的背景如下,我在c中使用套接字从网站获取内容,内容以gzip编码。 我想直接从流中读取内容并使用zlib对gzip内容进行编码。 但我如何知道gzip内容已启动且http标头已完成。 在我看来,我大致尝试了两种给我一些奇怪结果的方法。 首先,我在整个流中读取,并在终端中打印出来,我的http标题以“\ r \ n \ n \ n \ n”结束,就像我预期的那样,但是时间紧迫,我只需要检索一次响应以获取标题然后使用while循环读取内容,此处标题结束时不带“\ r \ n \ n \ n \ n”。 为什么? 哪种方式是阅读内容的正确方法? 我只是给你代码,这样你就可以看到我是如何从服务器获得响应的。 //first way (gives rnrn) char *output, *output_header, *output_content, **output_result; size_t size; FILE *stream; stream = open_memstream (&output, &size); char BUF[BUFSIZ]; while(recv(socket_desc, BUF, (BUFSIZ – 1), 0) > 0) […]

accept()线程安全吗?

我正在用C编写一个简单的网络服务器,用于我正在做的课程。 一个要求是我们实现一个线程池来处理使用pthreads的连接。 我知道我将如何大致这样做(在主线程中调用accept并将文件描述符传递给freee线程),但是我的朋友提出了一种替代方法而不是我想到的方法:在前面创建我的所有线程,让他们全部循环接受电话。 接受的想法是阻塞所有空闲线程,当连接进入时,只给出一个文件描述符。 然后当一个给定的线程完成一个连接时,它会循环回来并阻塞一个再次接受的调用。 使用accept()作为信号量的调用。 这样可以简化实现,因为您不需要跟踪哪些线程正忙,哪些线程已准备好进行连接。 理论上它也会降低延迟,因为线程可以立即开始执行。 我的问题是,这样安全吗? 我打算实施它并尝试一下,但我还没准备好,我很想知道答案。 我在谷歌和这里搜索stackoverflow,但找不到任何人这样做。 接受线程安全吗? 我假设这种方法会有更多的开销,因为你一直在运行所有的线程,这两种方法只是一个简单的内存/延迟权衡吗? 编辑:我不确定这应该是社区维基,如果它应该是道歉,我找不到按钮:P

在同一端口上接收多个组播源 – C,Linux

我有一个应用程序从同一端口上的多个组播源接收数据。 我能够收到数据。 但是,我试图考虑每个组的统计信息(即收到的消息,收到的字节数),并且所有数据都混淆了。 有谁知道如何解决这个问题? 如果我试着查看发件人的地址,那么它不是多播地址,而是发送机器的IP。 我使用以下套接字选项: struct ip_mreq mreq; mreq.imr_multiaddr.s_addr = inet_addr(“224.1.2.3”); mreq.imr_interface.s_addr = INADDR_ANY; setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)); 并且: setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &reuse, sizeof(reuse));

如何检测TCP套接字断开(使用C Berkeley套接字)

我正在使用循环从交流Berkeley套接字读出消息,但我无法检测套接字何时断开连接,所以我接受新的连接。 请帮忙 while(true) { bzero(buffer,256); n = read(newsockfd,buffer,255); printf(“%s\n”,buffer); }

唤醒线程在accept()调用时被阻塞

Linux上的套接字问题 我有一个在accept()调用时阻塞的工作线程。 它只是等待传入的网络连接,处理它,然后返回监听下一个连接。 当程序退出的时候,我如何发信号通知此网络工作线程(从主线程)从accept()调用返回,同时仍能正常退出其循环并处理其清理代码。 我试过的一些事情: pthread_kill发送信号。 感觉很难做到这一点,加上它不能可靠地允许线程执行它的关闭逻辑。 也使程序终止。 如果可能的话,我想避免发出信号。 pthread_cancel可以。 与上面相同。 这是对线程的严厉杀戮。 那个,线程可能正在做其他事情。 从主线程关闭listen套接字以使accept()中止。 这不可靠。 一些限制: 如果解决方案涉及使监听套接字无阻塞,那很好。 但我不想接受一个解决方案,该解决方案涉及线程每几秒钟通过一次选择呼叫唤醒以检查退出条件。 要退出的线程条件可能与退出的进程无关。 从本质上讲,我想要的逻辑看起来像这样。 void* WorkerThread(void* args) { DoSomeImportantInitialization(); // initialize listen socket and some thread specific stuff while (HasExitConditionBeenSet()==false) { listensize = sizeof(listenaddr); int sock = accept(listensocket, &listenaddr, &listensize); // check if exit condition has been set using […]

处理来自recv()TCP的部分返回

我一直在阅读Beej的网络编程指南,以了解TCP连接。 在其中一个示例中,简单TCP流客户端的客户端代码如下所示: if ((numbytes = recv(sockfd, buf, MAXDATASIZE-1, 0)) == -1) { perror(“recv”); exit(1); } buf[numbytes] = ‘\0’; printf(“Client: received ‘%s’\n”, buf); close(sockfd); 我将缓冲区设置为小于我发送的总字节数。 我不太确定如何获得其他字节。 我是否必须循环使用recv()直到收到’\0’ ? *关于服务器端的注意事项我也在实现他的sendall()函数,所以它应该实际上是将所有内容发送到客户端。 另见6.1。 指南中的简单流服务器 。

你如何限制C中套接字连接的带宽?

我正在使用BSD套接字编写客户端 – 服务器应用程序。 它需要在后台运行,不断传输数据,但不能从正常使用中占用网络接口的带宽。 根据接口的速度,我需要将此连接限制为某个最大传输速率。 以编程方式实现此目的的最佳方法是什么?

如何通知select()立即返回?

我有一个工作线程正在侦听TCP套接字以获取传入流量,并缓冲接收到的主线程要访问的数据(让我们称之为套接字A )。 但是,工作线程也必须做一些常规操作(比如每秒一次),即使没有数据进入。因此,我使用select()超时,这样我就不需要继续轮询。 (注意,在非阻塞套接字上调用receive()然后hibernate一秒钟并不好:即使主线程可能无法立即处理它,主线程也应立即可用传入数据。因此需要缓冲。) 现在,我还需要能够发信号通知工作线程立即执行其他操作; 从主线程,我需要让工作线程的select()返回。 现在,我已经解决了这个问题(从这里和这里基本采用的方法): 在程序启动时,工作线程为此创建了一个数据报(UDP)类型的附加套接字,并将其绑定到某个随机端口(让我们称之为套接字B )。 同样,主线程创建一个数据报套接字用于发送。 在调用select() ,工作线程现在在fd_set列出A和B. 当主线程需要发出信号时,它会将几个字节发送到sendto()几个字节到localhost上的相应端口。 回到工作线程中,如果在select()返回后B保留在fd_set ,则调用recvfrom()并忽略接收的字节。 这似乎工作得很好,但我不能说我喜欢这个解决方案,主要是因为它需要为B绑定一个额外的端口,还因为它增加了几个额外的套接字API调用,这可能会失败我猜 – 我不知道真的想要找出每个案件的适当行动。 我认为理想情况下,我想调用一些以A作为输入的函数,除了使select()返回之外什么都不做。 但是,我不知道这样的function。 (我想我可以例如shutdown()套接字,但副作用不是真的可以接受:) 如果这是不可能的,那么第二个最佳选择是创建一个比真正的UDP套接字更糟糕的B ,并且实际上并不需要分配任何有限的资源(超出合理的内存量)。 我想Unix域套接字就可以做到这一点,但是:解决方案不应该比现在的解决方案少得多,尽管有一些适量的#ifdef东西很好。 (我主要针对Windows和Linux – 并且顺便编写C ++。) 请不要建议重构以摆脱两个单独的线程。 这种设计是必要的,因为主线程可能会被长时间阻塞(例如,做一些密集的计算 – 我无法从最里面的计算循环开始定期调用receive() ),同时,有人需要缓冲传入的数据(由于我无法控制的原因,它不能是发送者)。 现在我正在写这篇文章,我意识到有人肯定会简单地回复“ Boost.Asio ”,所以我刚刚看了它……但是找不到明显的解决方案。 请注意,我也不能(轻松地)影响套接字A的创建方式,但如果需要,我应该能够让其他对象包装它。