现在的位置: 首页 > 综合 > 正文

TCP连接中断的处理

2019年08月10日 ⁄ 综合 ⁄ 共 2450字 ⁄ 字号 评论关闭

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连接建立,此时的通讯系统便很少需要人为的干

预,这样的模式做起来需要些技巧,留作以后讨论。

抱歉!评论已关闭.