我使用套接字在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
这是连接不再发生。 问题是什么? 提前致谢。
编辑:我真正想要的是,当我从头开始运行脚本后,销毁连接,它应该运行一个新的程序。 我该怎么做?
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)系统调用。
那么,因为连接是真正关闭时,另一方承认或超时。 这是正常的行为…
编辑:我没有实际检查你的代码,但从其他用户的意见,你做错了什么…