如何彻底销毁C中的套接字连接

我使用套接字在linux中创build了一个聊天客户端,并且我希望完全破坏这个连接。 以下是代码的相关部分:

int sock, connected, bytes_recieved , true = 1, pid; char send_data [1024] , recv_data[1024]; struct sockaddr_in server_addr,client_addr; int sin_size; label: if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("Socket"); exit(1); } if (setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,&true,sizeof(int)) == -1) { perror("Setsockopt"); exit(1); } server_addr.sin_family = AF_INET; server_addr.sin_port = htons(3128); server_addr.sin_addr.s_addr = INADDR_ANY; bzero(&(server_addr.sin_zero),8); if (bind(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr))== -1) { perror("Unable to bind"); exit(1); } if (listen(sock, 5) == -1) { perror("Listen"); exit(1); } printf("\nTCPServer Waiting for client on port 3128"); fflush(stdout); connected = accept(sock, (struct sockaddr *)&client_addr,&sin_size); //necessary code close(sock); goto label; 

但closures(sock)似乎并没有完全closures销毁连接,因为在去“标签”代码退出后显示错误信息

 Unable to bind: Address already in use 

这是连接不再发生。 问题是什么? 提前致谢。

编辑:我真正想要的是,当我从头开始运行脚本后,销毁连接,它应该运行一个新的程序。 我该怎么做?

Solutions Collecting From Web of "如何彻底销毁C中的套接字连接"

close调用只标记TCP套接字关闭。 它不再是可用的过程。 但内核可能仍然有一段时间(TIME_WAIT,2MLS等东西)的一些资源。

SO_REUSEADDR的设置应该消除绑定问题。

所以在调用setsockopt时,要确保true值真的非零(溢出错误可能会覆盖它):

 true = 1; setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,&true,sizeof(int)) 

pid变量是你的代码。 如果你使用fork (用于启动连接处理过程),那么你也应该在不需要的过程中关闭sock

首先为了命名,所以我们所有的命名都是一样的:

服务器端:

传递给listen()然后accept()的套接字让我们调用监听套接字。 accept()返回的套接字让我们调用接受的套接字。

客户端:

传递给connect()的套接字让我们调用连接/连接的套接字。


关于你的问题:

要终止accept() ed连接,首先使用shutdown()然后使用close ()close () 接受的套接字 (所调用的连接close () 。 为了在调用accept()之前接受一个新的连接循环, 不要再经过bind()listen()

只有关闭并关闭侦听套接字,如果你想摆脱accept()返回后发出挂起的 connect()

由于忘记关闭连接的插座,连接仍处于活动状态。 关闭监听套接字不会自动关闭连接的套接字。

 //necessary code close(connected); // <---- add this line close(sock); goto label; 

我不确定你为什么得到EADDRINUSE。 代码在linux和mac os上都能正常工作。

您应该使用shutdown(2)系统调用。

那么,因为连接是真正关闭时,另一方承认或超时。 这是正常的行为…

编辑:我没有实际检查你的代码,但从其他用户的意见,你做错了什么…