我已经在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("\TCPServer 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)似乎并没有完全关闭销毁连接,因为进入"标签"之后,代码将退出并显示错误消息
Unable to bind: Address already in use
那是连接不再发生。 问题可能是什么? 提前致谢。
编辑:我真正想要的是,在销毁连接后从头开始运行脚本时,它应该作为一个全新程序运行。 我该怎么做?
你为什么要这么做? 您应该循环回到accept之前,而不是重新创建服务器套接字。
为什么要关闭然后重新打开监听套接字,而不是在accept()周围循环?
可能的重复SO_REUSEADDR是什么意思(setsockopt选项)-Linux?
当我这样做时,我得到了答复You are connected to ,,这是我提供的用于检查连接是否建立的printf。 仅当客户端运行程序时才应建立连接,但是即使客户端没有在客户端上运行程序也应建立连接。 我现在应该怎么办?
"我得到的答复是您已连接到," ---从哪里来? 您的代码不包含该代码。 请显示相关代码。
printf("\
You are connected to %s , %d)", inet_ntoa(client_addr.sin_addr),ntohs(client_addr.sin_port)) ;这位于accept()的正下方。
serverfault.com/questions/329845/
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()连接,请先选择使用shutdown(),然后再使用close (),以关闭接受的套接字(您称为已连接)。
若要在调用accept()之前立即接受新的连接循环,请不要再次通过bind()和listen()。
如果要摆脱在accept()返回之后发出的挂起的connect(),则仅关闭并 strike>关闭监听套接字。
关闭前无需关机。 除非SD与其他进程共享,否则Close表示关闭,否则情况并非如此。 而且,您无需关闭监听套接字。
@ user207421:相应地修改了我的答案。
该连接仍处于活动状态,因为您忘记了关闭连接的插座。关闭监听套接字不会自动关闭连接的套接字。
//necessary code
close(connected); //
close(sock);
goto label;
我不确定为什么会收到EADDRINUSE。该代码在linux和mac os上都能正常工作。
您应该使用shutdown(2)系统调用。
我已经尝试过了,但是还是没有运气。 连接不会被破坏。
关闭前没有必要。
好吧,因为当另一方确认连接或经过一定超时后,连接实际上已关闭。这是正常现象...
编辑:我实际上并没有检查您的代码,但是从其他用户的注释中,您做错了什么...