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

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

### C#中处理TCP连接中断的异常解决方案 在C#中,处理TCP连接中断的异常需要对可能发生的异常进行捕获和处理。以下是一个示例代码,展示如何通过`try-catch`块捕获异常,并确保程序能够优雅地处理连接中断的情况[^1]。 ```csharp using System; using System.Net.Sockets; using System.Text; class Program { static void Main(string[] args) { TcpClient client = null; NetworkStream stream = null; try { // 创建一个TCP客户端实例 client = new TcpClient(); client.Connect(IPAddress.Parse("127.0.0.1"), 8080); Console.WriteLine("Connected to server."); // 获取网络流 stream = client.GetStream(); // 发送数据到服务器 string message = "Hello, Server!"; byte[] data = Encoding.ASCII.GetBytes(message); stream.Write(data, 0, data.Length); Console.WriteLine("Sent: " + message); // 接收服务器响应的数据 data = new byte[256]; int bytes = stream.Read(data, 0, data.Length); string responseData = Encoding.ASCII.GetString(data, 0, bytes); Console.WriteLine("Received: " + responseData); } catch (SocketException ex) { Console.WriteLine("SocketException: " + ex.Message); } catch (ObjectDisposedException ex) { Console.WriteLine("ObjectDisposedException: " + ex.Message); } catch (IOException ex) { Console.WriteLine("IOException: " + ex.Message); } catch (Exception ex) { Console.WriteLine("Exception: " + ex.Message); } finally { // 确保资源被正确释放 if (stream != null) { stream.Close(); } if (client != null) { client.Close(); } } } } ``` 在上述代码中,通过`try-catch`结构捕获了多种异常类型,包括但不限于`SocketException`、`ObjectDisposedException`和`IOException`。这些异常涵盖了常见的连接中断场景,例如服务器关闭连接或网络故障等[^1]。此外,在`finally`块中确保了无论是否发生异常,相关资源都会被正确释放。 #### 异常类型说明 - **SocketException**:当底层套接字操作失败时抛出,通常表示网络问题或服务器不可用。 - **ObjectDisposedException**:当尝试使用已关闭的对象(如已关闭的`TcpClient`或`NetworkStream`)时抛出。 - **IOException**:当读取或写入数据时发生错误,可能是由于连接中断或其他I/O问题引起的。 - **其他异常**:通过通用的`Exception`捕获未预料到的错误。 ### 注意事项 为了进一步增强程序的健壮性,可以定期检查`TcpClient`的状态,例如使用`client.Connected`属性来判断连接是否仍然有效。然而需要注意的是,`client.Connected`仅能提供当前状态的一个快照,不能完全依赖它来判断连接的有效性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值