2016-03-12 12 views
6

TCPステートを理解するための基本クライアントサーバーコードを記述しました。 クライアントコード:一部のTCPステートが端末に表示されない

#include <stdio.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <string.h> 

int main(){ 
int clientSocket; 
char buffer[1024]; 
struct sockaddr_in serverAddr; 
socklen_t addr_size; 

/*---- Create the socket. The three arguments are: ----*/ 
/* 1) Internet domain 2) Stream socket 3) Default protocol (TCP in this case) */ 
clientSocket = socket(PF_INET, SOCK_STREAM, 0); 

/*---- Configure settings of the server address struct ----*/ 
/* Address family = Internet */ 
serverAddr.sin_family = AF_INET; 
/* Set port number, using htons function to use proper byte order */ 
serverAddr.sin_port = htons(7891); 
/* Set IP address to localhost */ 
serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); 
/* Set all bits of the padding field to 0 */ 
memset(serverAddr.sin_zero, '\0', sizeof serverAddr.sin_zero); 

/*---- Connect the socket to the server using the address struct ----*/ 
addr_size = sizeof serverAddr; 
connect(clientSocket, (struct sockaddr *) &serverAddr, addr_size); 

/*---- Read the message from the server into the buffer ----*/ 
recv(clientSocket, buffer, 1024, 0); 

/*---- Print the received message ----*/ 
printf("Data received: %s",buffer); 

return 0; 
} 

サーバコード:

/****************** SERVER CODE ****************/ 

#include <stdio.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <string.h> 

int main(){ 
int welcomeSocket, newSocket; 
char buffer[1024]; 
struct sockaddr_in serverAddr; 
struct sockaddr_storage serverStorage; 
socklen_t addr_size; 
welcomeSocket = socket(PF_INET, SOCK_STREAM, 0); 
serverAddr.sin_family = AF_INET; 
serverAddr.sin_port = htons(7891); 
serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); 
memset(serverAddr.sin_zero, '\0', sizeof serverAddr.sin_zero); 

bind(welcomeSocket, (struct sockaddr *) &serverAddr, sizeof(serverAddr)); 

if(listen(welcomeSocket,5)==0) 
printf("Listening\n"); 
else 
    printf("Error\n"); 

addr_size = sizeof serverStorage; 
newSocket = accept(welcomeSocket, (struct sockaddr *) &serverStorage, &addr_size); 

strcpy(buffer,"Hello World\n"); 
send(newSocket,buffer,13,0); 

return 0; 
} 

時間の様々なポイントで、私は状態がLISTENING、FINWAIT2、CLOSE_WAITやTIME_WAIT、ESTABLISHED取得していますので、私は、コマンドnetstat -an | grep 7891を実行しています。 SYN_RECV、SYN_SENT、FINWAIT1、CLOSING、LAST ACKなどの他の状態を取得する方法。

私はさまざまなnetstatオプションとssオプションを試してきましたが、無駄にしませんでした。

+0

wiresharkはパケット転送シーケンスの学習には最適です。あなたのホストとクライアントの間のトラフィックをTCPのためだけにキャプチャすれば、暇つぶしでハンドシェーク、転送、クローズシーケンス全体を観察できます。 – user5976242

答えて

5

これらの段階が短すぎるため、SYN_RECVSYN_SENTなどは表示されません。たとえば、サーバー側で成功したaccept()の後にESTABLISHEDが設定されていると、以前の状態はすべてTCPスタックによって迅速に実行されます。 したがって、長い状態のtcp接続しか見ていません。

SYN-floodをシミュレートすることで、サーバ側でlisten(...,1)のバックログパラメータを使用し、return 0より前にスリープすることができます。そして、いくつかの別々のクライアントを立ち上げようとする。結果として、ETSABLISHEDの1といくつかのSYN_ *状態が得られます。

ファイナライズステートについてshutdown()close()に電話をかけ、その間にスリープを設定する必要があります。 fork()を使用して子プロセスを作成し、同期プリミティブを使用してTCP状態を理解することをお勧めします。

関連する問題