如何在C中完全销毁套接字连接

时间:2012-05-16 13:48:02

标签: c linux sockets network-programming

我使用socket在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;

但是close(sock)似乎并没有完全关闭破坏连接,因为在转到'label'后代码正在退出显示错误消息

Unable to bind: Address already in use

这就是连接没有再次发生。问题是什么?提前谢谢。

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

5 个答案:

答案 0 :(得分:27)

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

设置SO_REUSEADDR应该会删除绑定问题。

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

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

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

答案 1 :(得分:6)

首先是名称,所以我们都将相同的名称命名为相同:

服务器端:

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

客户方:

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


关于您的问题:

首先使用shutdown()后跟close ()终止accept()连接关闭已接受的套接字(您所谓的已连接)。 然后在调用accept()之前接受新的连接循环,不要再次通过bind()listen()

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

答案 2 :(得分:3)

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

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

我不确定你为什么会得到EADDRINUSE。代码在linux和mac os上运行良好。

答案 3 :(得分:1)

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

答案 4 :(得分:-2)

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

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