30

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

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;

但关闭(袜子)似乎并没有完全关闭破坏连接,因为在进入“标签”之后,代码正在退出并显示错误消息

Unable to bind: Address already in use

那就是连接不再发生。问题可能是什么?提前致谢。

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

4

5 回答 5

47

close调用仅标记 TCP 套接字已关闭。它不再被进程使用。但是内核可能仍会在一段时间内保留一些资源(TIME_WAIT、2MLS 等)。

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

因此,请确保true调用时的值确实非零setsockopt(溢出错误可能会覆盖它):

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

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

于 2012-05-18T10:37:58.347 回答
8

首先对于命名,所以我们都将相同的东西命名为相同的:

服务器端:

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

客户端:

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


关于你的问题:

要终止accept()ed 连接,可以选择先使用,然后关闭接受的套接字(你称之为连接的)。shutdown()close ()

然后在调用之前接受一个新的连接循环,accept()不要一遍bind()listen()一遍。

如果您想摆脱返回后发出的挂起的s,请仅关闭并关闭侦听套接字。 connect()accept()

于 2012-05-16T16:53:37.733 回答
7

连接仍然处于活动状态,因为您忘记关闭连接的套接字。关闭监听套接字不会自动关闭连接的套接字。

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

我不确定您为什么要获得 EADDRINUSE。该代码在 linux 和 mac os 上运行良好。

于 2012-05-18T06:05:20.147 回答
0

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

于 2012-05-16T16:01:00.250 回答
-2

好吧,因为当对方确认或在某个超时之后,连接才真正关闭。这是正常行为...

编辑:我实际上并没有检查您的代码,但从其他用户的评论来看,您做错了什么......

于 2012-05-16T13:50:47.913 回答