Tag: 套接字

如何在没有libcurl的情况下在C中发出HTTP get请求?

我想编写一个C程序来生成Get Request而不使用任何外部库。 这可能只使用C库,使用套接字吗? 我正在考虑制作一个http数据包(使用正确的格式)并将其发送到服务器。 这是唯一可能的方式还是有更好的方法?

如何将套接字重置为阻塞模式(在我将其设置为非阻塞模式后)?

关于将套接字设置为非阻塞模式,我已经读过这个。 http://www.gnu.org/software/libc/manual/html_mono/libc.html#File-Status-Flags 这是我做的: static void setnonblocking(int sock) { int opts; opts = fcntl(sock,F_GETFL); if (opts < 0) { perror("fcntl(F_GETFL)"); exit(EXIT_FAILURE); } opts = (opts | O_NONBLOCK); if (fcntl(sock,F_SETFL,opts) < 0) { perror("fcntl(F_SETFL)"); exit(EXIT_FAILURE); } return; } 如何将套接字设置回阻止模式? 我没有看到O_BLOCK标志? 谢谢。

在进程退出时释放绑定端口

如何确保在进程退出时正确释放绑定到端口的套接字,以便在没有使用EADDRINUSE的bind()失败的情况下重用端口? 我写了一个小程序,它只创建一个套接字,将它绑定到一个固定的端口,等待连接,然后立即终止。 当我重新运行程序时, bind()调用因EADDRINUSE而失败,但如果我等待几分钟,它就会成功。 有没有办法可以明确地“取消绑定”套接字,从而释放端口号?

TCP连接打开后是否会移动到另一个端口?

如果TCP套接字服务器在端口28081上侦听传入连接,然后接受连接并开始接收数据。 数据进入的端口是28081还是端口被更改。 例如,下面的伪代码中传入数据的端口是什么? 它仍然是28081还是操作系统分配了一个新端口?: bind listen (on port 28081) while 1 fd = accept fork if child process incoming data

使用C TCP套接字,可以’发送’返回零吗?

使用TCP套接字时,C sendfunction是否有可能返回零? 手册页只是说它将返回发送的字节数,但我不确定它是否只会在无法发送任何数据时返回-1。

在C中通过TCP(SOCK_STREAM)套接字传递结构

我有一个小型客户端服务器应用程序,我希望通过C而不是C ++中的TCP套接字发送整个结构。 假设结构如下: struct something{ int a; char b[64]; float c; } 我发现很多post说我需要使用pragma pack或者在发送和接收之前序列化数据。 我的问题是,使用JUST pragma pack还是仅仅序列化是否足够? 或者我需要同时使用两者吗? 此外,由于序列化是处理器密集型过程,这会使您的性能急剧下降,因此在没有使用外部库的情况下序列化结构的最佳方法是什么(我想要一个示例代码/算法)?

无法分配请求的地址 – 可能的原因?

我有一个由主服务器和分布式从服务器组成的程序。 从属服务器向服务器发送状态更新,如果服务器在固定时间内没有从特定从属设备收到消息,则它将从属设备标记为关闭。 这种情况一直在发生。 通过检查日志,我发现从服务器只能向服务器发送一个状态更新,然后永远不能发送另一个更新,总是无法调用connect()“无法分配请求的地址(99)。 奇怪的是,从服务器能够向服务器发送多个其他更新,并且所有连接都发生在同一端口上。 似乎这种失败的最常见原因是连接处于打开状态,但我无法找到任何未解决的问题。 还有其他可能的解释吗? 为了澄清,这是我如何连接: struct sockaddr *sa; // parameter size_t sa_size; //parameter int i = 1; int stream; stream = socket(AF_INET,SOCK_STREAM,0); setsockopt(stream,SOL_SOCKET,SO_REUSEADDR,&i,sizeof(i)); bindresvport(stream,NULL); connect(stream,sa,sa_size); 此代码用于获取与另一个服务器的连接,并且这4个调用中的任何一个失败都会导致该函数失败。

为什么假设send可能返回的数据少于阻塞套接字上传输的请求数据?

在流套接字上发送数据的标准方法一直是调用send和一大块数据进行写入,检查返回值以查看是否所有数据都已发送,然后再次调用send直到整个消息被接受为止。 例如,这是一个常见方案的简单示例: int send_all(int sock,unsigned char * buffer,int len){ 不存在 while(len> 0){ nsent = send(sock,buffer,len,0); if(nsent == -1)//错误 返回-1; buffer + = nsent; len – = nsent; } 返回0; //好的,发送了所有数据 } 甚至BSD手册也提到了这一点 …如果套接字上没有可用的消息空间来保存要传输的消息,则send() 通常会阻塞 … 这表明我们应该假设send可以在不发送所有数据的情况下返回。 现在我发现这个相当破碎,但即使是W. Richard Stevens在他的标准参考书中假定这是关于网络编程的 ,而不是在开头的章节中,但更高级的例子使用他自己的写(写所有数据)函数而不是调用write。 现在我认为这仍然或多或少地被破坏,因为如果send无法传输所有数据或接受底层缓冲区中的数据并且套接字阻塞,则send应该阻塞并在整个发送请求被接受时返回。 我的意思是,在上面的代码示例中,如果发送返回的数据发送的数量较少,将会发生的情况是,将使用新请求再次调用它。 自上次通话以来有什么变化? 最多几百个CPU周期已经过去,因此缓冲区仍然是满的。 如果发送现在接受数据,为什么它不能接受它? 否则,我们将以低效循环结束upp,我们试图在无法接受数据并继续尝试的套接字上发送数据,否则? 因此,如果需要,似乎解决方法会导致代码效率极低,在这种情况下,应该避免阻塞套接字,而应该使用非阻塞套接字和select。

close()没有正确关闭套接字

我有一个multithreading服务器(线程池),使用20个线程处理大量请求(一个节点最多500 /秒)。 有一个侦听器线程接受传入连接并将它们排队以供处理程序线程处理。 一旦响应准备就绪,线程就会写出到客户端并关闭套接字。 直到最近,一切似乎都很好,一个测试客户端程序在阅读响应后开始随机挂起。 经过大量挖掘后,似乎服务器的close()实际上并没有断开套接字。 我已经使用文件描述符编号为代码添加了一些调试打印,我得到了这种类型的输出。 Processing request for 21 Writing to 21 Closing 21 close()的返回值为0,否则将打印另一个调试语句。 使用挂起的客户端输出此输出后,lsof将显示已建立的连接。 SERVER 8160 root 21u IPv4 32754237 TCP localhost:9980-> localhost:47530(ESTABLISHED) 客户端17747 root 12u IPv4 32754228 TCP localhost:47530-> localhost:9980(ESTABLISHED) 就像服务器永远不会将关闭序列发送到客户端一样,这种状态会一直挂起,直到客户端被终止,让服务器端处于关闭等待状态 SERVER 8160 root 21u IPv4 32754237 TCP localhost:9980-> localhost:47530(CLOSE_WAIT) 此外,如果客户端指定了超时,它将超时而不是挂起。 我也可以手动运行 call close(21) 在gdb的服务器中,客户端将断开连接。 这可能在50,000个请求中发生一次,但可能不会在较长时间内发生。 Linux版本:2.6.21.7-2.fc8xen Centos版本:5.4(最终版) 套接字动作如下 服务器: […]

如何在C(主机名和域信息)中找到当前计算机的完整主机名?

在C项目(POSIX)中,如何获取当前系统的完全限定名称? 例如,我可以通过从unistd.h执行gethostname()来获取我的机器的主机名。 这可能会给我machine3作为回报,但我实际上是在寻找machine3.somedomain.com 。 我如何获取此信息? 如果可能的话,我不想使用system()来执行此操作。