所以我目前正在编写一个 C++ 程序,它是一个点对点即时通讯工具。因此,当程序启动时,它会侦听指定端口上的传入连接,但也会允许用户通过输入其 IP 地址来启动与另一台主机的连接。现在,套接字connect()函数 AFAIK 的工作方式与send()函数非常相似,但它会传输一个 SYN 数据包,直到服务器以accept()响应或服务器拒绝连接被关闭。所以主要问题是......如果我创建一个套接字然后调用listen()函数,如果我在同一个端口上调用connect函数,我会得到一个错误吗?如果是这样,有没有办法创建一个 SYN 数据包,然后调用send()函数将其传输到指定主机?该程序与客户端-服务器模型不同,因为运行该程序的任何主机都将充当客户端和服务器。
2 回答
套接字可以是listen
或connect
。它不能两者兼得。
如果您希望每台主机既是客户端又是服务器,那么每个主机都需要两个套接字。
至少在 MacOS X 上,您在connect(2)
手册页中尝试执行的操作有一条特定的错误消息:
[EOPNOTSUPP]
因为socket正在监听,所以不允许连接。
现在套接字 connect() 函数 AFAIK 的工作方式与 send() 函数非常相似,但它会传输一个 SYN 数据包,直到服务器以 accept() 响应或服务器拒绝连接被关闭
这是不正确的开始。connect()
发送 SYN 没问题,但 ACK 回复来自对等 TCP 堆栈,可能早在服务器应用程序接近调用accept()
. 这是因为监听积压队列。
所以你的动机已经很可疑了。
如果我创建一个套接字然后调用listen()函数,如果我在同一个端口上调用connect函数会出错吗?
是的。你不能那样做。你没有激发这个问题,但你甚至不需要这样做。您无需为正在侦听入站连接的出站连接使用相同的本地端口。
有没有办法创建一个 SYN 数据包,然后调用 send() 函数将其传输到指定的主机?
你可以手动发送一个 SYN,如果你能弄清楚如何创建一个原始 IP 套接字,但你不能让 TCP/IP 将它识别为 TCP 连接的一部分。同样,这与您的问题无关。
我什至不相信你实际上有问题。您只需要一个侦听套接字、接受的套接字和用于出站连接的套接字,所有这些都以通常的方式创建。不需要任何技巧。