エコーサーバーを作成するために、次のコードを記述しました(stdoutに書き込んだデータは、PCからサーバーに移動してPCに戻ります)。コードでは、ソケットにSO_LINGERオプションを設定しました。したがって、Ctrl+を押しCてclient.cppがサーバー.cppにFINを送信すると、client.cppのclose()は、server.cppのソケットがFINを返送するまで10秒待機する必要があります。
しかし、私が見つけたのは、client.cppがすぐに実行を終了Ctrlし、 +Cが押された後に終了し、close()関数でさえ-1を返さなかったということでした。これは、反対側がl_lingerに記載されている時間より前にFINを送信しない場合に必要です。有効期限が切れます(サーバーがFINを送信しなかったか、tcpdumpにリストされている必要があります。)サーバー側は、端末でCtrl+を押さない限りFINを送信しませんでした。サーバーの端末で+Cを押すまでのtcpdumpは、スクリーンショットに示されています。CtrlC
上記で強調表示されている行は、クライアントの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()が待機していないのはなぜですか?