/// TCP监听服务器端 [C#源代码来自http://www.showjim.com/] using System; using System.Collections.Generic; using System.Net; using System.Net.Sockets; using System.Threading; using System.Text; using System.IO; using sys.collections.generic; namespace sys.net { /// <summary> /// TCP监听服务器端 /// </summary> public class tcpListener { /// <summary> /// 处理客户端连接的委托 /// </summary> /// <param name="threadId">Socket连接访问关键字</param> /// <returns>是否继续(未结束)</returns> public delegate bool listerHandle(int threadId); /// <summary> /// TCP监听服务器端连接 /// </summary> private TcpListener listener = null; /// <summary> /// 是否开始监听 /// </summary> private bool isStart = false; /// <summary> /// 开始一个会话时的默认应答 /// </summary> private byte[] startSend; /// <summary> /// 每个客户端Socket连接 /// </summary> private Dictionary<int, Socket> sockets; //Socket.RemoteEndPoint.ToString();返回客户端IP地址与端口号,如127.0.0.1:80 /// <summary> /// 处理客户端连接的委托 /// </summary> private listerHandle listenSocket; #region 构造服务器端TCP连接实例 /// <summary> /// 构造服务器端TCP连接实例 /// </summary> /// <param name="port">服务端口</param> /// <param name="ListenSocket">处理客户端连接的委托</param> /// <param name="startSendByte">开始一个会话时的默认应答</param> public tcpListener(int port, listerHandle ListenSocket, byte startSendByte) { if (port > 0 && port < 65536 && ListenSocket != null) { try { listener = new TcpListener(IPAddress.Any, port); //IPAddress.Parse("127.0.0.1") listener.Start(); startSend = new byte[] { startSendByte }; listenSocket = ListenSocket; sockets = new Dictionary<int, Socket>(); isStart = true; Thread socketThread = new Thread(getSockets); socketThread.Start(); } catch (System.Security.SecurityException) { } //防火墙错误 catch (Exception error) {//一般错误,比如调用Stop结束、端口被占用 close(); sys.exception.debug.throwException(System.Reflection.MethodBase.GetCurrentMethod(), "服务器端口" + port.ToString() + @"TCP连接失败) " + error.ToString()); } } } #endregion #region 关闭服务器端TCP连接 /// <summary> /// 关闭服务器端TCP连接 /// </summary> ~tcpListener() { close(); } /// <summary> /// 关闭服务器端TCP连接 /// </summary> public void close() { isStart = false; listenSocket = null; if (sockets != null) { foreach (int threadId in sockets.Keys) { try { sockets[threadId].Close(); } catch { } } sockets = null; } if (listener != null) { listener.Stop(); listener = null; } } #endregion #region 循环获取并响应客户端请求 /// <summary> /// 循环获取并响应客户端请求 /// </summary> private void getSockets() { while (isStart && listener != null) { Socket socket = null; Thread socketThread = null; try { socket = listener.AcceptSocket(); if (startSend != null) socket.Send(startSend); int key = sys.pub.identity; sockets.Add(key, socket); (socketThread = new Thread(new ParameterizedThreadStart(listen))).Start(key); socketThread.IsBackground = true; } catch { if (socket != null) { socket.Close(); socket = null; } if (socketThread != null && socketThread.IsAlive) { socketThread.Abort(); } } } } #endregion #region 服务器端监听处理主线程 /// <summary> /// 服务器端监听处理主线程 /// </summary> /// <param name="identity">客户端标识</param> private void listen(object identity) { int key = (int)identity; Socket socket = sockets.get(key, null); if (socket != null) { try { for (bool noQuit = true; isStart && noQuit && socket.Connected; noQuit = listenSocket(key)) ; } finally { socket.Close(); sockets.remove(key); } } } #endregion #region 接收客户端的数据 /// <summary> /// 接收客户端的一个字节 /// </summary> /// <param name="threadId">Socket连接访问关键字</param> /// <returns>-2表示出错,-1表示结束</returns> public int receiveByte(int threadId) { byte[] bytes = new byte[1]; int length = _receive(threadId, bytes, 0, 1); return length == 1 ? (int)bytes[0] : (length == 0 ? -1 : -2); } /// <summary> /// 接收客户端的一个15位正整数 /// </summary> /// <param name="threadId">Socket连接访问关键字</param> /// <returns>-2表示出错,-1表示结束</returns> public int receiveInt15(int threadId) { byte[] bytes = new byte[2]; int value = _receive(threadId, bytes, 0, 2); if (value == 2) { if ((value = BitConverter.ToInt16(bytes, 0)) < 0) value = 0; } else value = (value < 0 ? -2 : -1); return value; } /// <summary> /// 接收客户端的一个31位正整数 /// </summary> /// <param name="threadId">Socket连接访问关键字</param> /// <returns>-2表示出错,-1表示结束</returns> public int receiveInt31(int threadId) { byte[] bytes = new byte[4]; int value = _receive(threadId, bytes, 0, 4); if (value == 4) { if ((value = BitConverter.ToInt32(bytes, 0)) < 0) value = 0; } else value = (value < 0 ? -2 : -1); return value; } /// 接收客户端的一个63位正整数 /// </summary> /// <param name="threadId">Socket连接访问关键字</param> /// <returns>-2表示出错,-1表示结束</returns> public long receiveInt63(int threadId) { byte[] bytes = new byte[8]; long value = -2; int length = _receive(threadId, bytes, 0, 8); if (length == 8) { if ((value = BitConverter.ToInt64(bytes, 0)) < 0) value = 0; } else value = (length < 0 ? -2 : -1); return value; } /// <summary> /// 接收客户端的数据到字节数组的指定位置 /// </summary> /// <param name="threadId">Socket连接访问关键字</param> /// <param name="bytes">字节数组</param> /// <returns>实际接收长度,失败为-1</returns> public int receive(int threadId, byte[] bytes) { return isStart && bytes != null && bytes.Length > 0 ? _receive(threadId, bytes, 0, bytes.Length) : -1; } /// <summary> /// 接收客户端的数据到字节数组的指定位置 /// </summary> /// <param name="threadId">Socket连接访问关键字</param> /// <param name="bytes">字节数组</param> /// <param name="startIndex">开始位置</param> /// <returns>实际接收长度,失败为-1</returns> public int receive(int threadId, byte[] bytes, int startIndex) { return isStart && bytes != null && bytes.Length > startIndex ? _receive(threadId, bytes, startIndex, bytes.Length - startIndex) : -1; } /// <summary> /// 接收客户端指定长度的数据到字节数组的指定位置 /// </summary> /// <param name="threadId">Socket连接访问关键字</param> /// <param name="bytes">字节数组</param> /// <param name="startIndex">开始位置</param> /// <param name="length">接收长度</param> /// <returns>实际接收长度,失败为-1</returns> public int receive(int threadId, byte[] bytes, int startIndex, int length) { return isStart && bytes != null && startIndex >= 0 && length > 0 && bytes.Length >= startIndex + length ? _receive(threadId, bytes, startIndex, length) : -1; } /// <summary> /// 接收客户端指定长度的数据到字节数组 /// </summary> /// <param name="threadId">Socket连接访问关键字</param> /// <param name="length">接收长度</param> /// <returns>字节数组</returns> public byte[] receiveBytes(int threadId, int length) { byte[] bytes = null; if (length > 0 && length != _receive(threadId, bytes = new byte[length], 0, length)) bytes = null; return bytes; } /// <summary> /// 接收客户端指定长度的数据到字节数组的指定位置 /// </summary> /// <param name="threadId">Socket连接访问关键字</param> /// <param name="bytes">字节数组</param> /// <param name="startIndex">开始位置</param> /// <param name="length">接收长度</param> /// <returns>实际接收长度,失败为-1</returns> private int _receive(int threadId, byte[] bytes, int startIndex, int length) { int receiveLength = -1; Socket socket = sockets.get(threadId, null); if (socket != null) { try { for (int nextLength = length; nextLength != 0; nextLength -= receiveLength) startIndex += (receiveLength = socket.Receive(bytes, startIndex, nextLength, SocketFlags.None)); receiveLength = length; } catch { receiveLength = -1; socket.Close(); } } return receiveLength; } /// <summary> /// 接收客户端指定长度的数据到字节数组的指定位置 /// </summary> /// <param name="socket">Socket连接</param> /// <param name="bytes">字节数组</param> /// <param name="startIndex">开始位置</param> /// <param name="length">接收长度</param> /// <returns>实际接收长度,失败为-1</returns> private int _receive(Socket socket, byte[] bytes, int startIndex, int length) { int receiveLength = -1; try { for (int nextLength = length; nextLength != 0; nextLength -= receiveLength) startIndex += (receiveLength = socket.Receive(bytes, startIndex, nextLength, SocketFlags.None)); receiveLength = length; } catch { receiveLength = -1; socket.Close(); } return receiveLength; } #endregion #region 发送数据到客户端 /// <summary> /// 发送字节数组到客户端 /// </summary> /// <param name="threadId">Socket连接访问关键字</param> /// <param name="bytes">字节数组</param> /// <returns>是否成功</returns> public bool send(int threadId, byte[] bytes) { return isStart && bytes != null && bytes.Length > 0 && _send(threadId, bytes); } /// <summary> /// 发送字节数组的指定位置数据到客户端 /// </summary> /// <param name="threadId">Socket连接访问关键字</param> /// <param name="bytes">字节数组</param> /// <param name="startIndex">起始位置</param> /// <returns>是否成功</returns> public bool send(int threadId, byte[] bytes, int startIndex) { return isStart && bytes != null && startIndex >= 0 && bytes.Length > startIndex && _send(threadId, bytes, startIndex, bytes.Length - startIndex); } /// <summary> /// 发送字节数组的指定位置数据到客户端 /// </summary> /// <param name="threadId">Socket连接访问关键字</param> /// <param name="bytes">字节数组</param> /// <param name="startIndex">起始位置</param> /// <param name="length">发送长度</param> /// <returns>是否成功</returns> public bool send(int threadId, byte[] bytes, int startIndex, int length) { return isStart && bytes != null && startIndex >= 0 && length >= 0 && bytes.Length >= startIndex + length && _send(threadId, bytes, startIndex, length); } /// <summary> /// 按照默认编码方式发送字符串到客户端 /// </summary> /// <param name="threadId">Socket连接访问关键字</param> /// <param name="sendString">字符串</param> /// <returns>是否成功</returns> public bool send(int threadId, string sendString) { return isStart && sendString != null && sendString.Length != 0 && _send(threadId, Encoding.Default.GetBytes(sendString)); } /// <summary> /// 发送字符串到客户端 /// </summary> /// <param name="threadId">Socket连接访问关键字</param> /// <param name="sendString">字符串</param> /// <param name="code">编码方式</param> /// <returns>是否成功</returns> public bool send(int threadId, string sendString, Encoding code) { return isStart && sendString != null && sendString.Length != 0 && code != null && _send(threadId, code.GetBytes(sendString)); } /// <summary> /// 发送字节数组到客户端 /// </summary> /// <param name="threadId">Socket连接访问关键字</param> /// <param name="bytes">字节数组</param> /// <returns>是否成功</returns> private bool _send(int threadId, byte[] bytes) { bool isSend = false; Socket socket = sockets.get(threadId, null); if (socket != null) { try { socket.Send(bytes, SocketFlags.None); isSend = true; } catch { socket.Close(); } } return isSend; } /// <summary> /// 发送字节数组的指定位置数据到客户端 /// </summary> /// <param name="threadId">Socket连接访问关键字</param> /// <param name="bytes">字节数组</param> /// <param name="startIndex">起始位置</param> /// <param name="length">发送长度</param> /// <returns>是否成功</returns> private bool _send(int threadId, byte[] bytes, int startIndex, int length) { bool isSend = false; Socket socket = sockets.get(threadId, null); if (socket != null) { try { socket.Send(bytes, startIndex, length, SocketFlags.None); isSend = true; } catch { socket.Close(); } } return isSend; } #endregion #region 读取客户端指定长度数据保存到文件 /// <summary> /// 读取客户器端指定长度数据保存到文件 /// </summary> /// <param name="threadId">Socket连接访问关键字</param> /// <param name="fileName">文件名</param> /// <param name="length">文件字节数</param> /// <returns>是否成功</returns> public bool saveFile(int threadId, string fileName, long length) { bool isSave = false; if (isStart && fileName != null && fileName.Length != 0 && length > 0 && sockets.ContainsKey(threadId)) { FileStream fileStream = null; try { fileStream = new FileStream(fileName, FileMode.CreateNew, FileAccess.Write, FileShare.None, pub.streamBufferLength); } catch { } if (fileStream != null) { isSave = saveFile(threadId, fileStream, 0, length, pub.streamBufferLength); fileStream.Close(); if (!isSave) File.Delete(fileName); } } return isSave; } /// <summary> /// 读取客户器端指定长度数据保存到文件流 /// </summary> /// <param name="threadId">Socket连接访问关键字</param> /// <param name="fileStream">文件流</param> /// <param name="startIndex">起始位置</param> /// <param name="length">字节长度</param> /// <returns>是否成功</returns> public bool saveFile(int threadId, FileStream fileStream, long startIndex, long length) { return saveFile(threadId, fileStream, startIndex, length, pub.streamBufferLength); } /// <summary> /// 读取客户器端指定长度数据保存到文件流 /// </summary> /// <param name="threadId">Socket连接访问关键字</param> /// <param name="fileStream">文件流</param> /// <param name="startIndex">起始位置</param> /// <param name="length">字节长度</param> /// <param name="bufferLength">缓存区字节长度</param> /// <returns>是否成功</returns> public bool saveFile(int threadId, FileStream fileStream, long startIndex, long length, int bufferLength) { bool isSave = false; if (isStart && fileStream != null && startIndex >= 0 && length > 0 && bufferLength > 0) { long endIndex = startIndex + length; if (endIndex > 0) { try { fileStream.SetLength(endIndex); fileStream.Seek(startIndex, SeekOrigin.Begin); } catch { } int readLength; byte[] bytes = new byte[bufferLength]; isSave = true; try { while (isSave && length >= bufferLength) { if (isSave = ((readLength = receive(threadId, bytes)) == bufferLength)) { fileStream.Write(bytes, 0, readLength); length -= readLength; } } if (isSave && length != 0 && (isSave = (receive(threadId, bytes, 0, readLength = (int)length) == readLength))) fileStream.Write(bytes, 0, readLength); } catch { isSave = false; } } } return isSave; } #endregion #region 用法示例 /// <summary> /// 服务器监听端口 /// </summary> private const int examplePort = 9999; /// <summary> /// 开始一个会话时的默认应答 /// </summary> private static byte exampleStartSendByte = 200; /// <summary> /// TCP监听服务器实例 /// </summary> private static sys.net.tcpListener exampleListener = new sys.net.tcpListener(examplePort, exampleHandle, exampleStartSendByte); /// <summary> /// 处理客户端连接的委托 /// </summary> /// <param name="key">Socket连接访问关键字</param> /// <returns>是否继续(未结束)</returns> private static bool exampleHandle(int key) { #region 接收客户端的数据 int byteValue = exampleListener.receiveByte(key); //接收一个字节 int int31Value = exampleListener.receiveInt31(key); //接收一个31位整数 byte[] bytes=new byte[int31Value]; int length = exampleListener.receive(key, bytes, 0, int31Value); //接收一个字节数组 #endregion #region 发送数据到客户端 bool isSend = exampleListener.send(key, bytes, 0, bytes.Length); //发送一个字节数组 #endregion return false; } #endregion } }
参考这两个C#程序(含注释) 1
最新推荐文章于 2024-07-20 17:30:58 发布