- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我编写了以下代码来创建一个echo 服务器(我写入标准输出的数据从我的 PC 移动到服务器并返回到我的 PC)。在代码中,我在套接字中设置了 SO_LINGER 选项。因此,当我按下 Ctrl+C 导致 client.cpp 将 FIN 发送到 server.cpp 时,client.cpp 的 close() 应该等待server.cpp 的套接字发送回 FIN 10 秒。
但我发现 client.cpp 在按下 Ctrl+C 后立即完成执行并退出,甚至 close() 函数没有返回 -1 如果另一方在 l_linger 中提到的时间到期之前没有发送 FIN,它应该返回 -1(我确信服务器没有发送 FIN或者它必须已在 tcpdump 中列出。)除非我在其终端上按下 Ctrl+C,否则服务器端不会发送 FIN。在服务器终端上按下 Ctrl+C 之前的 tcpdump 显示在屏幕截图中:
上面突出显示的行是客户的 FIN。
客户端.cpp:
int main()
{
int clifd;
clifd=socket(AF_INET,SOCK_STREAM, IPPROTO_TCP);
sockaddr_in serv;
bzero(&serv, sizeof(serv));
serv.sin_family=AF_INET;
serv.sin_port=htons(3345);
inet_aton("127.0.0.1", &(serv.sin_addr));
linger lin;
unsigned int y=sizeof(lin);
lin.l_onoff=1;
lin.l_linger=10;
setsockopt(clifd,SOL_SOCKET, SO_LINGER,(void*)(&lin), y);
connect(clifd, (sockaddr*)(&serv), sizeof(serv));
int n,m;
char data[100];
char recvd[100];
for(;;)
{
fgets(data, 100,stdin );
n=strlen(data);
cout<<"You have written "<<n<<endl;
if(n>0)
{
while(n>0)
{
m=write(clifd,data,n);
n=n-m;
}
}
n=read(clifd, recvd, 100);
cout<<"Server echoed back "<<n<<endl;
if(n>0)
{
while(n>0)
{
m=fputs(data,stdout);
cout<<"m is"<<m<<endl;
fflush(stdout);
n=n-m;
}
//cout<<data<<endl;
}
}
int z=close(clifd);
if(z==-1)
cout<<"close returned -1 "<<endl; ***//this doesn't get printed***
}
server.cpp:
void reflect(int x)
{
int n;
int m;
char data[100];
cout<<"Entered reflect function"<<endl;
for(;;)
{
n=read(x,data, 100);
cout<<"Client sent "<<n<<endl;
if(n>0)
{
while(n>0)
{
m=write(x,data,n);
n=n-m;
}
cout<<"Successfully echoed back to client"<<endl;
}
}//end of for loop
}
int main()
{
sockaddr_in serv;
bzero(&serv, sizeof(serv));
serv.sin_family=AF_INET;
serv.sin_port=htons(3345);
inet_aton("127.0.0.1", &(serv.sin_addr));
int servfd=socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
int x;
x=bind(servfd, (sockaddr*)(&serv), sizeof(serv));
cout<<"Bind returned"<<x<<endl; //this displays x as 0
listen(servfd, 5);
sockaddr cli;
int connfd;
pid_t id=-1;
socklen_t siz=sizeof(cli);
for(;;)
{
if((connfd=accept(servfd, &cli, &siz))>=0)
id=fork();
if(id==0)
reflect(connfd);
else
continue;
}
}
为什么客户端的 close() 没有等待?
最佳答案
Why is client's close() not waiting?
您没有在客户端调用 close()
。紧接在 close()
调用之前的 for
循环永远不会退出,因此永远不会发生 close()
。
在控制台中键入 CTRL-C 会导致程序立即退出,而不执行任何剩余操作。
由于永远不会调用 close()
,所以您的其余问题(close()
应该等待吗?我应该使用 closesocket()
? 等)没有实际意义。
如果您确实希望能够退出 for(;;)
循环,请尝试如下操作:
for(;;)
{
if(fgets(data, 100,stdin ) == NULL)
break;
... rest of loop goes here ...
然后,当您运行客户端程序时,不要使用 CTRL-C 终止它,而是键入 CTRL- D 作为行中唯一的字符。
关于c++ - SO_LINGER 选项不会导致 close() 等待,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11439986/
我正在编写一个多线程winsock应用程序,但我在关闭套接字时遇到了一些问题。首先,同时打开的套接字数量是否有限制?假设一次有 32 个套接字。 我在其中一个套接字上建立了连接,并传递信息,一切顺利。
那里有很多混杂的信息。 我只是想确保数据已完全发送。我应该关闭/关闭还是使用 SO_LINGER 和超时关闭? 我在 Linux 下使用带 epoll 的非阻塞套接字,在 OSX 下使用 kqueue
我编写了以下代码来创建一个echo 服务器(我写入标准输出的数据从我的 PC 移动到服务器并返回到我的 PC)。在代码中,我在套接字中设置了 SO_LINGER 选项。因此,当我按下 Ctrl+C 导
将 SO_LINGER 与 udp 套接字一起使用是否有效? 如果是,您能否描述一下 SO_LINGER 适合 udp 套接字的情况或说明性示例? 一点背景: 我从未使用过 SO_LINGER 选项,
我在一个同时连接到许多 URL 的网站上工作(我们希望达到每分钟约 600 个),无论我尝试什么,总是有数千个 TIME_WAIT 仍然打开。我知道这些对 TCP 连接至关重要,但它们正在使用所有可用
我试图在连接上强制重置 TCP。建议的方法是将 SO_LINGER 设置为 0 并调用 close()。 我正在这样做,但连接仍处于 ESTABLISHED 状态。套接字以非阻塞模式运行。操作系统是
我想我理解选项的正式含义。在我现在处理的一些遗留代码中,使用了该选项。客户提示 RST 作为从其一侧关闭连接时对 FIN 的响应。 我不确定我是否可以安全地删除它,因为我不明白什么时候应该使用它。 您
我正在编写一个使用套接字的跨平台客户端应用程序,该应用程序是用 C++ 编写的。当服务器向我发送信息后,它正在硬关闭套接字,我遇到了问题。 我一直在阅读关于这个主题的其他帖子,我对这种方法的正确与错误
我已阅读 When is TCP option SO_LINGER (0) required?以及其他几个相关的问题和答案,但我无法重现这些帖子中解释的任何 SO_LINGER 行为。我将在这里分享我
我是一名优秀的程序员,十分优秀!