TCP连接中断的处理

    技术2022-05-19  24

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

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


    最新回复(0)