TCP連接中斷的處理

Client-Server模式的TCP/IP網絡編程中,當客戶端與服務器端建立起TCP連接時,我們會

遇到連接中斷的情況,此時怎樣處理呢?

首先,我們應使兩端的通訊進程儘量"健壯"些,以避免一些干擾。爲此,我們可以調用S

ignal (SIGINT, SIG_IGN)、singnal (SIGHUP, SIG_IGN)、signal (SIGQUIT, SGI_IGN),

來屏蔽掉一些可以導致進程終止的信號。

其次,當一TCP連接中斷時,對基於該連接的socket的系統調用read的返回值爲0,由此,

我們可以設計服務器端的代碼如下:

# include

# include

# include

# include

# include

# include

struct msgdata {

long msgtype;

char msgdata [1024];

}

main (argc, argv)

int argc;

char **argv;

{

int forkid;

if (argc !=2

{

printf (:usages:%s localport/n", argv[0]);

exit(2);

}

signal (SIGINT, SIG_IGN)

signal (SIGHUP, SIG_IGN)

signal (SIGQUIT, SIG_IGN)

signal (SIGTERM, SIG_IGN)

for (;;) {

if((forkid=fork())==0) lmsgl(atoi (argv[1]);

else

{

wait (( int*)0); /* here this process is waiting for the creat

ed

sleep(5)

} /*process to be dead

}

}

lmsgl (localport)

int localport;

{

long forkid;

int namelen, newsock, sock, i, datalen;

int goback ();

struct msgdata td, rd;

struct sockaddr-in sin={AF_INET};

sin. sin-prort=localport;

datalen=sizeof (struct msgdata);

namelen=sizeof (sin);

if((sock=socket (AF-INET, DOCK-STREAM, IPPROTO-TCP))<=0)

{

perror ("socket");

exit (1);

}

if(bind (sock, &sin, sizeof (sin))<0)

{ perror ("bind");

exit(2);

}

if (getsockname (sock, &sin, &namelen)<0)

{

perror ("getsockname");

exit(2);

}

printf ("Server bound to port %u 0x%x/n", ntohs (sin, sin-port), sin.s

in-port);

if (listen (sock, 5)<0)

{ perror ("listen");

exit (4);

}

if ((newsock=accept (sock, &sin, &namelen))<0)

{ perror ("accept");

exit (5);

}

switch (forkid=fork()) {

case-1;

/*error number returned!

printf ("fork error/n:);

perror ("fork");

exit (5);

case

close (sock);

for (;;)

{

i=read (newsock, &rd, datalen);

if (i==0)

{

printf("/nthe connection is terminated!/n");

close (newsock);

exit (6);

}

/*Bere we kill the child process and

/*send SIGHLD to the parent process

do something we are interesting.....

}

default: /*the parent process

close (sock);

signal (SIGHLD, goback (newsock));

/*catching the SIGCHLD signal, jump to the beginning

for (;;)

//do something we are interesting.....

{

i=write (newsock, &td, datalen);

if (i=-1)

{

printf ("TCP/IP write error!/n");

perror ("write");

continue;

} /*end of switch

} /*end of lmsge

goback (newsock)

int newsock;

{

signal (SIGINT, SIG_IGN);

close (newsock);

printf ("Go Back to Beginning/n");

exit (7);

}

以上代碼中,一祖父進程調用fork ()創建一父進程,然後掛起父進程,等待客戶端的連

接請求,一旦TCP連接建立起來,父進程又創造一子進程;此時父進程負責向已建立連接的ne

wsock中寫入信息,子進程負責從newsock中讀取信息。當TCP連接中斷時,子進程的read返回

值爲0,那麼它便終止運行;同時向父進程發送SIGCHLD信號。在父進程中,我們設置signal

(SIGCHLD, goback),當捕捉到SIGCHLD信號時,提示中斷信息,然後終止進程。由於我們在祖

父進程中,用wait ( (int *) 0)來實現進程同步,這時祖父進程便被激活,它啓動另外一父

進程,等待客戶端的連接請求,當請求到來時,新的TCP連接便能建立起來。

另外,在某些情況下,我們可以把Client-Server模式做得對等起來,也就是說一端既可

以等待連接要求,也可以主動地請求連接。這樣當TCP連接中斷時,通信系統的兩端便能智能

地在server、Client之間隨機轉換,直到TCP連接建立,此時的通訊系統便很少需要人爲的幹

預,這樣的模式做起來需要些技巧,留作以後討論。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章