那网络异常断开原因主要有那些呢?归纳起来主要有以下两种:
1、客户端程序异常。
对于这种情况,我们很好处理,因为客户端程序异常退出会在服务端引发ConnectionReset的Socket异常(就是WinSock2中的10054异常)。只要在服务端处理这个异常就可以了。
2、网络链路异常。
如:网线拔出、交换机掉电、客户端机器掉电。当出现这些情况的时候服务端不会出现任何异常。这样的话上面的代码就不能处理这种情况了。对于这种情况在MSDN里面是这样处理的,我在这里贴出MSDN的原文:
如果您需要确定连接的当前状态,请进行非阻止、零字节的 Send 调用。如果该调用成功返回或引发 WAEWOULDBLOCK 错误代码 (10035),则该套接字仍然处于连接状态;否则,该套接字不再处于连接状态。
但是我在实际应用中发现,MSDN说的这种处理方法在很多时候根本无效,无法检测出网络已经异常断开了。那我们该怎么办呢?
我们知道,TCP有一个连接检测机制,就是如果在指定的时间内(一般为2个小时)没有数据传送,会给对端发送一个Keep-Alive数据报,使用的序列号是曾经发出的最后一个报文的最后一个字节的序列号,对端如果收到这个数据,回送一个TCP的ACK,确认这个字节已经收到,这样就知道此连接没有被断开。如果一段时间没有收到对方的响应,会进行重试,重试几次后,向对端发一个reset,然后将连接断掉。
在Windows中,第一次探测是在最后一次数据发送的两个小时,然后每隔1秒探测一次,一共探测5次,如果5次都没有收到回应的话,就会断开这个连接。但两个小时对于我们的项目来说显然太长了。我们必须缩短这个时间。那么我们该如何做呢?我要利用Socket类的IOControl()函数。我们来看看这个函数能干些什么:
使用 IOControlCode 枚举指定控制代码,为 Socket 设置低级操作模式。
命名空间:System.Net.Sockets
程序集:System(在 system.dll 中)
语法
C#
public int IOControl (
IOControlCode ioControlCode,
byte[] optionInValue,
byte[] optionOutValue
)
参数
ioControlCode
一个 IOControlCode 值,它指定要执行的操作的控制代码。
optionInValue
Byte 类型的数组,包含操作要求的输入数据。
optionOutValue
Byte 类型的数组,包含由操作返回的输出数据。
返回值
optionOutValue 参数中的字节数。
如:
socket.IOControl(IOControlCode.KeepAliveValues, inOptionValues, null);
我们要搞清楚的就是inOptionValues的定义,在C++里它是一个结构体。我们来看看这个结构体:
struct tcp_keepalive
...{
u_long onoff; //是否启用Keep-Alive
u_long keepalivetime; //多长时间后开始第一次探测(单位:毫秒)
u_long keepaliveinterval; //探测时间间隔(单位:毫秒)
};
在C#中,我们直接用一个Byte数组传递给函数:http://www.devdao.com/
uint dummy = 0;
byte[] inOptionValues = new byte[Marshal.SizeOf(dummy) * 3];
BitConverter.GetBytes((uint)1).CopyTo(inOptionValues, 0);//是否启用Keep-Alive
BitConverter.GetBytes((uint)5000).CopyTo(inOptionValues, Marshal.SizeOf(dummy));//多长时间开始第一次探测
BitConverter.GetBytes((uint)5000).CopyTo(inOptionValues, Marshal.SizeOf(dummy) * 2);//探测时间间隔
具体实现代码:
public static void AcceptThread()
...{
Thread.CurrentThread.IsBackground = true;
while (true)
...{
uint dummy = 0;
byte[] inOptionValues = new byte[Marshal.SizeOf(dummy) * 3];
BitConverter.GetBytes((uint)1).CopyTo(inOptionValues, 0);
BitConverter.GetBytes((uint)5000).CopyTo(inOptionValues, Marshal.SizeOf(dummy));
BitConverter.GetBytes((uint)5000).CopyTo(inOptionValues, Marshal.SizeOf(dummy) * 2);
try
...{
Accept(inOptionValues);
}
catch ...{ }
}
}
private static void Accept(byte[] inOptionValues)
...{
Socket socket = Public.s_socketHandler.Accept();
socket.IOControl(IOControlCode.KeepAliveValues, inOptionValues, null);
UserInfo info = new UserInfo();
info.socket = socket;
int id = GetUserId();
info.Index = id;
Public.s_userList.Add(id, info);
socket.BeginReceive(info.Buffer, 0, info.Buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallBack), info);
}
好了,这样就成功了。
分享到:
相关推荐
### 利用Keep-Alive处理Socket网络异常断开的方法 #### 一、引言 在网络编程中,确保网络连接的稳定性和健壮性至关重要。在TCP/IP协议栈中,网络异常断开是一种常见现象,例如当客户端突然断电或者网络连接中断时...
在C#中利用Keep-Alive处理Socket网络异常断开的方法[参考].pdf
本实例展示了如何使用C#中的Socket类来判断网络是否断开,涵盖了Socket编程、TCP/IP协议、数据发送和接收、网络断开判断、异常处理、客户端/服务器端编程、数据编码和解码、程序设计等多个知识点。
总的来说,通过Socket判断远端网络是否断开,主要依赖于心跳机制、异常处理和套接字选项。在实际应用中,还需要结合具体的业务需求和网络环境,选择合适的策略来确保网络连接的稳定性。同时,注意在网络恢复时,及时...
4. **异常处理**:使用`try-catch`结构来捕获并处理可能出现的异常,如网络中断、Socket错误等,并记录异常信息。 #### 关键知识点总结 1. **Socket连接状态判断**: - 利用`ClientSocket.Connected`属性判断当前...
这种方法的缺点是探测到连接正常,但是传输数据的时可能连接会异常断开。 3. 传输层 TCP 连接检测机制(Keep-Alive) Keep-Alive 机制是一种检测 TCP 连接是否有效的方法。默认情况下关闭。如果在指定的时间内没有...
在IT行业中,网络通信是不可或缺的一部分,而C#语言提供了强大的Socket编程接口,使得开发者能够构建可靠的网络应用程序。本文将详细讲解如何在C#中处理Socket的断开重连问题,以及如何实现循环接收数据。 Socket是...
综上所述,Socket服务器端在断开后重新打开时,客户端的自动重连机制主要依赖于心跳检测、异常处理、重试策略和超时设定。通过这些技术手段,可以确保在网络不稳定或服务器短暂离线的情况下,客户端仍能恢复与服务器...
而"In C#中利用Keep-Alive处理Socket网络异常断开的方法 .txt"可能详细介绍了如何利用TCP的Keep-Alive机制来辅助心跳检查,Keep-Alive是TCP协议内置的特性,可以在无数据传输时自动发送探测报文,但其默认配置可能并...
断开连接可能由网络故障、客户端或服务器端程序异常终止等原因引起。在C#中,可以使用`Socket.Connected`属性检查连接状态,但这个属性在某些情况下可能不准确。因此,建议在尝试发送数据时捕获`SocketException`...
需要妥善处理网络异常、超时等问题,并且要确保在程序结束时释放所有占用的资源,例如关闭Socket句柄。 #### 6. 客户端与服务器端的通信示例 开发环境中,一个常用的组合是Visual Studio 2013配合MFC。在MFC中,...
7. **异常处理**:Socket编程中,网络异常如连接中断、数据传输错误等是常见的问题。因此,编写健壮的Socket程序需要良好的异常处理机制,以确保程序在遇到问题时能够恢复或优雅地关闭。 8. **数据编码与解码**:在...
在这个项目中,你可能会看到如何处理网络异常,如超时或连接断开,以及如何优雅地关闭Socket连接。 总之,C#中的Socket网络编程允许开发者构建功能强大的网络应用程序,如聊天应用、文件传输工具等。通过理解和实践...
Java Socket网络编程是Java开发中一个重要的组成部分,它允许应用程序通过网络进行通信,实现客户端与服务器之间的数据交换。本教程将深入探讨Java Socket编程的基本概念、原理和实践应用。 一、Socket基本概念 ...
- 断开重连逻辑,检测到连接异常时,关闭Socket并尝试重新连接。 这个代码示例对于学习和理解如何在C#中实现稳定的Socket通信非常有帮助,特别是对于需要处理网络不稳定情况的应用来说,如在线游戏、实时监控、...
在Socket编程中,网络异常、数据传输异常等情况很常见,因此需要进行适当的错误处理。例如,连接超时、网络中断、数据读写异常等都需要捕获并适当地处理。 6. **多线程在Socket编程中的应用**: 当服务器需要同时...
"Socket长连接异常处理" 在 Java 网络编程中,Socket 长连接是指在客户端和服务器端之间保持一个长期的连接,以便于数据的...Socket 长连接异常处理需要注意以上这些问题,以确保网络程序的稳定运行和高效传输数据。
在Socket编程中,必须妥善处理各种网络异常,如`IOException`,确保程序的健壮性。例如,当网络中断或服务器关闭时,需要捕获并适当地处理异常。 7. **阻塞与非阻塞模式** 默认情况下,Socket和ServerSocket操作...
在IT领域,网络编程是不可或缺的一部分,而Socket接口是实现跨平台网络通信的主要工具。无论是Linux还是Windows操作系统,开发者都需要了解如何判断一个Socket连接的状态,以便于处理异常情况,保证程序的稳定性和...