C++ 服务器套接字编程TCP连接地址已在使用中
这对我现在有用。但是,我必须确保客户端重新连接在两分钟后启动。因为再次启动客户端需要一段时间,并且抛出已经在使用的地址。但一分钟后,它被允许绑定和倾听,而这并没有发生。这是我需要等待的时间吗 我编写了一个服务器套接字程序,其中服务器和客户端运行在同一台主机上。服务器仅写入(服务器不执行读取操作),而客户端仅从服务器读取(客户端不执行写入操作)。当我终止服务器进程并尝试再次运行时,它会显示地址已在使用中。当使用SO_REUSEADDR时,它允许我重用端口,但客户端不再从服务器接收数据。服务器代码的一部分C++ 服务器套接字编程TCP连接地址已在使用中,c++,unix,tcp,client-server,C++,Unix,Tcp,Client Server,这对我现在有用。但是,我必须确保客户端重新连接在两分钟后启动。因为再次启动客户端需要一段时间,并且抛出已经在使用的地址。但一分钟后,它被允许绑定和倾听,而这并没有发生。这是我需要等待的时间吗 我编写了一个服务器套接字程序,其中服务器和客户端运行在同一台主机上。服务器仅写入(服务器不执行读取操作),而客户端仅从服务器读取(客户端不执行写入操作)。当我终止服务器进程并尝试再次运行时,它会显示地址已在使用中。当使用SO_REUSEADDR时,它允许我重用端口,但客户端不再从服务器接收数据。服务器代码的
while(1)
{
write(newsockfd,"I got your message",18); //Server Publishes data all day
}
部分客户端代码:-
while(1)
{
n = read(sockfd,buffer,255);//Read all server publishes and store them
if (n == 0)
error("ERROR reading from socket");
printf("Here is the message: %s \n",buffer);
bzero(buffer,256); //Buffer set to Null again
}
如果在连接上我尝试netstat-a,我可以看到我的服务器正在监听端口,比如20001,我将它绑定到该端口。但是,即使客户端和服务器都在运行,我仍然无法看到建立连接。客户端不断打印从接收到的数据
服务器。当我终止服务器进程时,我看到客户端只是在每次读取后打印换行符作为缓冲区设置为NULL。现在我的问题是,如果已经建立了连接,并且连接现在已经终止,这会阻止服务器在同一端口上侦听吗?我的主要问题是,为什么没有其他进程监听该端口?所以,REUSEADDR允许服务器绑定和重用ADDR。这是因为服务器和客户端运行在同一台主机上吗?如果终止是不公平的,如何处理(第二个问题)。在注释中添加read check as后,我仍然看到客户端正在运行,netstat给出了以下输出:-
xyz@xyz:~$ netstat -a | grep -i 2001
tcp 0 0 localhost:47058 localhost:2001 CLOSE_WAIT
tcp 0 0 localhost:2001 localhost:47058 FIN_WAIT2
提前感谢看起来您对TCP的工作原理有点困惑 当您终止并重新启动服务器时,客户端不再连接,因此它需要关闭其TCP连接的末端,即调用套接字描述符,然后创建一个新的套接字描述符,然后重新连接 您可能缺少从客户端套接字上的返回的0(零),这意味着另一端已关闭其连接端 。当我终止服务器进程并尝试再次运行时,它会显示地址已在使用中。当使用SO_REUSEADDR时,它允许我重用端口,但客户端不再从服务器接收数据
您不能让您的客户机继续运行,就好像服务器上什么也没发生一样。客户端应该检测到断开的连接,并从一端关闭套接字,然后重新启动连接建立过程。旧的联系已经一去不复返了 检查从Read返回的状态某些读取不能为0,因为服务器没有发布任何内容,因为没有新数据?更重要的是,我想知道为什么服务器不允许再次绑定相同的端口,因为没有人在侦听它?测试小于0时如何检查等于0?看,如果读取结果小于零,这很重要,因为发出了错误信号。如果读取结果等于零,这很重要,因为这意味着对等方已关闭连接。如果读取结果大于零,这一点很重要,因为这是告诉缓冲区中加载了多少字节的唯一方法。您必须正确处理所有3种情况。您不需要将缓冲区归零:这是cargo cult编程。您确实需要注意
n
的值:例如,printf(“这是消息:%.*s\n”,n,buffer)我试过这个。但是当我在read=0if(n==0){//error(“error reading from socket”);close(sockfd);reconnect(argv[1],portno);}
之后关闭客户端上的套接字时,这对我现在起作用了。但是,我必须确保客户端重新连接在两分钟后启动。因为再次启动客户端需要一段时间,并且抛出已经在使用的地址。但是一分钟后,它就可以绑定和监听了,这在TCP/IP世界中是不可能发生的。我们通常把执行bind(2)
,listen(2)
,accept(2)
排序的进程称为服务器,而执行连接(2)
的进程称为客户端。您的都是,因此您必须对两侧应用相同的规则(例如,在侦听套接字上设置so\u REUSEADDR
)。您要区分套接字读取返回的错误(-1
)和EOF(零)。第一个是真正的问题,第二个是有效的协议条件。我现在不使用SO_REUSEADDR。我正在检查读取返回0,如果是,请睡眠一段时间并重新连接。但服务器需要一些时间来绑定、侦听和接受,您可以说大约需要2分钟。我现在使用check==0
进行读取。