我編寫了下面的代碼,以便使echo服務器(我寫入stdout的數據從我的PC移動到服務器並返回到我的PC)。在代碼中,我在套接字中設置了SO_LINGER選項。所以,當我按下Ctrl鍵+ç其中造成client.cpp一個FIN發送到server.cpp的client.cpp的close()應該等待10秒的server.cpp的套接字發回FIN。SO_LINGER選項不會導致close()等待
但我發現的是,client.cpp立即執行完畢和後退出按Ctrl +ç按下甚至的close()funcion沒有返回-1它應該有如果對方在l_linger提到的時間到期之前沒有發送FIN(我確信服務器沒有發送FIN或者它必須已經在tcpdump中列出)。服務器端沒有發送FIN除非我按Ctrl + C在其終端人。直到我按下Ctrl鍵+服務器的終端基於C tcpdump的顯示在屏幕截圖:
突出顯示的上述線是客戶端的FIN。
client.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()不等待?
爲什麼你認爲'Ctrl + C'不會終止你的應用程序(因此不會讓它有機會看到套接字被關閉)?您不會在您的客戶端應用程序中捕獲到SIGINT,並且您看到的「FIN」可能是由於套接字被應用程序「強行關閉」而「關閉」。 – Chad 2012-07-11 19:35:42