我正在做一些网络测试,我正在用两个只使用函数的小 C 程序连接 linux 机器:
connect()
连接后,进行了一些小计算并将其记录到本地文件中,我指示其中一个程序关闭连接,然后在同一端口上运行 netcat 监听器。然后第一个程序重试连接并连接到 netcat。
我想知道是否有人可以建议是否可以在释放端口的同时保持初始连接并将连接传递给该端口上的 netcat(这样初始连接就不会关闭)。
最佳答案
每个 TCP 连接都由四元组(目标 IP 地址、目标端口、源 IP 地址、源端口)定义,因此无需“释放”任何一台机器上的端口。
服务器进程在 accept()
建立新连接后立即 fork()
是很常见的。父进程关闭它的连接描述符副本(由 accept()
返回),并等待新的连接。子进程关闭原始套接字描述符,并执行应处理实际连接的所需程序或脚本。在许多情况下, child 将连接描述符移动到标准输入和标准输出(使用 dup2()
),这样执行的脚本或程序甚至不需要知道它连接到远程客户端:它写入标准输出的所有内容都会发送到远程客户端,而远程客户端发送的所有内容都可以从标准输入读取。
如果存在应处理连接的现有进程,并且两个进程之间存在 Unix 域套接字连接(流、数据报或 seqpacket 套接字;没有区别),则可以将连接描述符作为SCM_RIGHTS
辅助消息。参见 man 2 sendmsg
, man 2 recvmsg
, man 3 cmsg
, 和 man 7 unix
了解详情。这仅适用于同一台机器上的 Unix 域套接字,因为内核实际上复制描述符从一个进程到另一个;真的,内核做了一些时髦的魔法来实现这一点。
如果你的服务器端逻辑是这样的
- 对于每个传入连接:
- 做一些计算
- 将计算存储到文件中
- 将来自连接的传入数据存储到文件(或标准输出)
那么我推荐使用pthreads
。只需创建所需数量的线程,通过在监听套接字上调用 accept()
让所有线程等待传入连接,并让每个线程自己处理连接。您甚至可以将 stdio.h
I/O 用于文件 I/O。对于更复杂的输出——每个 block 有多个语句——,每个输出流都需要一个 pthread_mutex_t
,并记住在释放互斥量之前对它执行 fflush()
。我怀疑一个单一的多线程程序可以完成所有这些工作,并且如果被中断(SIGINT
又名 CTRL+C
)会很好地退出,不应超过三百行 C。
关于您可以将 TCP 连接从一个进程传递到另一个进程吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18936614/