SocketTcpServer
自定义SocketTcpServer,虽然现在有很多这样的组件,但是有时候还是需要把它集成在你的框架或者产品中,不需要特别强大的功能,根据需求定制。最基本的一个问题是判断数据包的结束,没有像supersocket那样默认以换行作为一个命令的结束,如果需要可以改善。
public interface ISocketTcpServer
{
void Listen();
void Stop();
void SendData(byte[] data, Socket client); event ReceiveDataHandler ReceivedDataEvent;
event OnlineChangeHandler OnlineChangeEvent;
event ErrorHandler ErrorEvent;
} public delegate void ReceiveDataHandler(SocketState state); public delegate void OnlineChangeHandler(int onlines, EndPoint client); public delegate void ErrorHandler(string error, EndPoint client); public class SocketTcpServer : ISocketTcpServer
{
private readonly Socket _tcpSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
public readonly EndPoint LocalPoint;
public readonly List<SocketState> ClientList = new List<SocketState>();
public bool IsListening; public SocketTcpServer(IPEndPoint localPoint)
{
LocalPoint = localPoint;
} public void Listen()
{
_tcpSocket.Bind(LocalPoint);
_tcpSocket.Listen();
_tcpSocket.BeginAccept(AcceptClientCallBack, _tcpSocket);
IsListening = true;
} public void Stop()
{
IsListening = false;
foreach (var state in ClientList)
{
state.ClientSocket.Close();
}
ClientList.Clear();
_tcpSocket.Close();
OnlineChangeEvent?.Invoke(ClientList.Count, new IPEndPoint(IPAddress.Any, ));
} private void AcceptClientCallBack(IAsyncResult ar)
{
var server = ar.AsyncState as Socket;
if (IsListening && server != null)
{
try
{
var client = server.EndAccept(ar);
var clientState = new SocketState()
{
ClientSocket = client,
RemotePoint = client.RemoteEndPoint,
};
var tem = ClientList.FirstOrDefault(x => x.RemotePoint.Equals(clientState.RemotePoint));
if (tem != null)
{
tem.ClientSocket.Close();
ClientList.Remove(tem);
}
ClientList.Add(clientState);
BeginReveive(client);
OnlineChangeEvent?.Invoke(ClientList.Count, client.RemoteEndPoint);
}
catch (Exception error)
{
ErrorEvent?.Invoke(error.Message, null);
}
finally
{
server.BeginAccept(AcceptClientCallBack, server);
}
}
} private void BeginReveive(Socket client)
{
if (client.Connected)
{
var state = new SocketState()
{
ClientSocket = client,
RemotePoint = client.RemoteEndPoint,
};
client.BeginReceiveFrom(
state.Buffer,
,
state.Buffer.Length,
SocketFlags.None,
ref state.RemotePoint,
ReceiveCallback,
state);
}
} private void ReceiveCallback(IAsyncResult ar)
{
var state = ar.AsyncState as SocketState;
try
{
if (state != null && state.ClientSocket.Connected)
{
state.DataLen = state.ClientSocket.EndReceiveFrom(ar, ref state.RemotePoint);
if (state.DataLen == )
{
state.ClientSocket.Close();
var tem = ClientList.FirstOrDefault(x => x.RemotePoint.Equals(state.RemotePoint));
ClientList.Remove(tem);
OnlineChangeEvent?.Invoke(ClientList.Count, state.RemotePoint);
}
else
{
byte[] receivedData = new byte[state.DataLen];
Array.Copy(state.Buffer, , receivedData, , state.DataLen);
state.Buffer = receivedData;
ReceivedDataEvent?.Invoke(state);
}
}
}
catch (Exception error)
{
ErrorEvent?.Invoke(error.Message, state.RemotePoint);
state.ClientSocket.Close();
var tem = ClientList.FirstOrDefault(x => x.RemotePoint.Equals(state.RemotePoint));
ClientList.Remove(tem);
OnlineChangeEvent?.Invoke(ClientList.Count, state.RemotePoint);
}
finally
{
if (state != null) BeginReveive(state.ClientSocket);
}
} public void SendData(byte[] data, Socket client)
{
if (client.Connected)
{
var state = new SocketState()
{
ClientSocket = client,
RemotePoint = client.RemoteEndPoint,
Buffer = data,
DataLen = data.Length,
};
client.BeginSendTo(data, , data.Length, SocketFlags.None, state.RemotePoint, SendCallback, state);
}
} private void SendCallback(IAsyncResult ar)
{
var state = ar.AsyncState as SocketState;
try
{
if (state != null && state.ClientSocket.Connected)
{
state.ClientSocket.EndSendTo(ar);
}
}
catch (Exception error)
{
ErrorEvent?.Invoke(error.Message, state.RemotePoint);
}
} public event ReceiveDataHandler ReceivedDataEvent; public event OnlineChangeHandler OnlineChangeEvent; public event ErrorHandler ErrorEvent;
} public class SocketState
{
public byte[] Buffer = new byte[*];
public Socket ClientSocket;
public int DataLen;
public EndPoint RemotePoint;
}
SocketTcpServer的更多相关文章
- C#网络编程系列(两)它Socket同步TCPserver
声明原文 笔者:竹zz 本文地址http://blog.csdn.net/zhujunxxxxx/article/details/44258719 转载请注明出处 文章系列文件夹 C#网络编程系列文 ...
- Unity C# 自定义TCP传输协议以及封包拆包、解决粘包问题
本文只是初步实现了一个简单的TCP自定协议,更为复杂的协议可以根据这种方式去扩展. TCP协议,通俗一点的讲,它是一种基于socket传输的由发送方和接收方事先协商好的一种消息包组成结构,主要由消息头 ...
- QT创建TCP Socket通信
最近在学习QT,了解到QT可以进行SOCKET网络通信,进行学习,并建立一个简单的聊天DEMO.为了测试是否能与VS2012下的程序进行通信,在VS2012下建立一个客户端程序,进行通信测试,发现可以 ...
- Android之socket服务端
import java.io.DataInputStream; import java.io.IOException; import java.io.PrintWriter; import java. ...
- 8.9.网络编程_Socket 远程调用机制
1.网络编程 1.1.网络编程概述: 通过通信线路(有线或无线)可以把不同地理位置且相互独立的计算机连同其外部设备连接起来,组成计算机网络.在操作系统.网络管理软件及网络 通信协议的管理和协调下,可以 ...
- 1、Socket通信
[TCP] 服务器端:无目标插座升级为有目标插座后,就可以通过有目标的插座收发数据 客户端: 实战:此案例有利于理解Socket的工作流程. 缺点:服务器只能接收1个客户端的连接,因为只写了一个Acc ...
随机推荐
- laravel 控制器方法里存get值 和 blade 模板获得闪存值的方法
//get 方式把id传到路由 <a href="/admin/reply/add/{{$comment -> id}}" class="btn btn-bl ...
- python核心编程第六章练习6-15
转换.(a)给出两个可识别格式的日期,比如MM/DD/YY或者DD/MM/YY格式.计算出两个日期之间的天数.(b)给出一个人的生日,计算此人从出生到现在的天数,包括所有的闰月.(c)还是上面的例子, ...
- js 原生对象排序
//对象属性排序 function compare(propertyName) { return function (object1, object2) { var value1 = object1[ ...
- 在python中使用matplotlib中的Matplotlib-Animation “No MovieWriters Available”
在使用官方的示例代码中,一部分使用了ffmpeg 在执行时会报如题一样的错误 解决: 下载windows的版本,解压,然后将bin目录加入系统环境变量的路径中 如:D:\Program Files\f ...
- hdu 1532(最大流)
Drainage Ditches Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) ...
- ios 打包
/usr/bin/xcodebuild -scheme Moon -sdk iphoneos -workspace Moon.xcworkspace -configuration Release cl ...
- NodeJS利用mongoose模糊查询MongoDB
在Node.js中,直接硬编码可以 Posts.where('title',/答案/); 但是 通过 字符串构造 不行 var qs = '/'+req.query.search+'/'; Posts ...
- BZOJ1880: [Sdoi2009]Elaxia的路线
题意:求最短路最长公共距离. 考虑每一条边,如果满足dis(s1,u)+len+dis(v,t1)==dis(s1,t1) && dis(s2,u)+len+dis(v,t2)==di ...
- Spring之JDBC模板jdbcTemplate
要使用Jdbctemplate 对象来完成jdbc 操作.通常情况下,有三种种方式得到JdbcTemplate 对象. 第一种方式:我们可以在自己定义的DAO 实现类中注入一个Da ...
- eventUtil
var eventUtil = { // 添加句柄 addHandler: function(element, type, handler) { if(element.addEventListener ...