/// <summary> /// 处理连接请求 /// </summary> private void processAccept(SocketAsyncEventArgs e) { //限制线程的访问 acceptSemaphore.WaitOne(); //得到客户端的对象 ClientPeer client = clientPeerPool.Dequeue(); client.ClientSocket = e.AcceptSocket; Console.WriteLine("客户端连接成功:" + client.ClientSocket.RemoteEndPoint.ToString()); //开始接受数据 startRecive(client); e.AcceptSocket = null; startAccept(e); }
/// <summary> /// 处理接收 /// </summary> private void processAccept(SocketAsyncEventArgs e) { //把可以用得线程减少一个,先开启减少一个 ,当我们取内容的时候就调用 acceptSemaphore.WaitOne(); //通过异步来调用是这样子调用的 Socket clientSocket = e.AcceptSocket; // ClientPeer clientPeer = clientPool.Dequeue(); clientPeer.ClientSocket = clientSocket; // startReceive(clientPeer); //然后就可以一直接收客户端得到得数据 //这里是,完成一个,传递e 的可以减少new e 的开销 e.AcceptSocket = null; // 主要是回调 socket.AcceptAynsc startAccept(e); }
/// <summary> /// 断开连接 /// </summary> /// <param name="client">当前指定的客户端</param> /// <param name="reason">断开原因</param> public void Disconnect(ClientPeer client, string reason) { try { if (client == null) { throw new Exception("当前客户端为空 , 无法断开连接"); } // 通知应用层,客户端断开连接了 app.OnDisconnect(client); client.Disconnect(); clientPool.EnqueueClient(client); // 回收对象,以便下次使用 sema.Release(); // 退出信号量 , 返回前一个计数 } catch (Exception e) { Console.WriteLine(e.Message); } }
public void Disconnect(ClientPeer client, string reason) { try { if (client == null) { throw new Exception("当前指定的客户端连接为空,无法断开连接!"); } Console.WriteLine(client.ClientSocket.RemoteEndPoint.ToString() + "客户端断开了连接,原因:" + reason); //通知应用层 application.OnDisconnect(client); client.Disconnect(); clientPeerPool.Enqueue(client); acceptSemaphore.Release(); }catch (Exception e) { Console.WriteLine(e.Message); throw; } }
/// <summary> /// 处理接收的请求 /// </summary> /// <param name="e"></param> private void processReceive(SocketAsyncEventArgs e) { //反方向获得对象,因为这里是Compeleted 获得的对象,那个方法又被指定了对象,所以就限制了方向 ClientPeer client = e.UserToken as ClientPeer; // if (client.ReceiveArgs.SocketError == SocketError.Success && client.ReceiveArgs.BytesTransferred > 0) { //Console.WriteLine("数据符合逻辑"); //获取收据的长度 byte[] packet = new byte[client.ReceiveArgs.BytesTransferred]; //拷贝到数组中 Buffer.BlockCopy(client.ReceiveArgs.Buffer, 0, packet, 0, client.ReceiveArgs.BytesTransferred); //客户端自身解释 client.StartReceive(packet); //解释完成以后,又得开启接收 (C# 可能就是这样,就收后流可能要重新设置) startReceive(client); } else { //如果是进入else ,那么就是网络失败了, //如果传输的数据为0 if (client.ReceiveArgs.BytesTransferred == 0) { // if (client.ReceiveArgs.SocketError == SocketError.Success) { // 如果是正常,那么就是 Socket Client 主动断开连接 DisConnect(client, "客户端主动断开连接"); } else { //否则就是网络异常断开连接 DisConnect(client, client.ReceiveArgs.SocketError.ToString()); } } } }
/// <summary> /// 处理连接请求 /// </summary> private void ProcessAccept(SocketAsyncEventArgs e) { ///限制线程的访问 计数。 假设客户端100个 每调用一次加一。等到100就等待 有位置就继续 acceptSemaphore.WaitOne(); //得到客户端的对象 //1,原始方法 //Socket socket = e.AcceptSocket; //2,更改方法。 但是每次都需要new 耗费性能。所以新建一个对象池。。。。 //ClientPeer clientPeer = new ClientPeer(); //clientPeer.SetSocket(e.AcceptSocket); //3, ClientPeer clientPeer = clientPeerPool.Dequeue(); clientPeer.clientSocket = e.AcceptSocket; Console.WriteLine("连接的客户端:" + clientPeer.clientSocket.RemoteEndPoint.ToString()); //开始接收数据 StartReceive(clientPeer); //继续进行处理 //一直进行接收客户端发来的数据 伪循环 e.AcceptSocket = null; StartAccept(e); }
/// <summary> /// 断开连接 /// </summary> /// <param name="client">断开的客户端对象</param> /// <param name="reason">断开的原因</param> public void Disconnect(ClientPeer client, string reason) { try { // 清空数据 if (client == null) { throw new Exception("当前指定的客户端连接对象为空,无法断开连接"); } // 通知应用层 这个客户端断开连接 Console.WriteLine(client.ClientSocket.RemoteEndPoint + "客户端断开连接 原因:" + reason); application.OnDisconnect(client); client.Disconnect(); //回收对象方便下次使用 clientPeerPool.Enqueue(client); acceptSemaphore.Release(); } catch (Exception e) { Console.WriteLine(e.Message); } }
/// <summary> /// 开始接收数据 /// </summary> /// <param name="client"></param> private void startReceive(ClientPeer client) { try { // 异步接收对象,这个接收的相的异步数据对象是连接的时候得到的 // 把 client 的ui想 bool result = client.ClientSocket.ReceiveAsync(client.ReceiveArgs); if (result == false) { //防止 客户端异步接收不成功,然后手动启动接收 processReceive(client.ReceiveArgs); } else { // 如果接收完成了的话,就处理完成,一般没有的 //因为我们是强连接 ///processReceiveCompeleted(client.ReceiveArgs); } } catch (Exception e) { Console.WriteLine(e.Message); } }
/// <summary> /// 开启服务器 /// </summary> /// <param name="port">端口号</param> /// <param name="maxCount">最大连接数量</param> public void Start(int port, int maxCount) { try { serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); acceptSemaphore = new Semaphore(maxCount, maxCount); clientPeerPool = new ClientPeerPool(maxCount); ClientPeer tempClientPeer = null; for (int i = 0; i < maxCount; i++) { tempClientPeer = new ClientPeer(); clientPeerPool.Enqueue(tempClientPeer); } serverSocket.Bind(new IPEndPoint(IPAddress.Any, port)); serverSocket.Listen(maxCount); Console.WriteLine("服务器启动"); startAccept(null); } catch (Exception e) { Console.WriteLine(e.Message); } }
public void Enqueue(ClientPeer clientPeer) { clientPeerQueue.Enqueue(clientPeer); }
/// <summary> /// 一条数据解析完成的处理 /// </summary> /// <param name="client">对应的连接对象</param> /// <param name="value">解析出来的一个具体能使用的类型</param> private void receiveCompleted(ClientPeer client, SocketMsg msg) { //给应用层 让其使用 application.OnReceive(client, msg); }
public void Enqueue(ClientPeer client) { clientPeerPool.Enqueue(client); }
/// <summary> /// 数据解析完成的处理 /// </summary> /// <param name="client"></param> /// <param name="obj"></param> private void ReceiveCompeleted(ClientPeer client, SocketMsg msg) { // 给应用层 , 让其使用 app.OnReceive(client, msg); }
/// <summary> /// 一条数据解析完成的处理 /// </summary> /// <param name="clientPeer"></param> /// <param name="value"></param> private void reciveCompleted(ClientPeer clientPeer, SocketMessage msg) { application.OnRecive(clientPeer, msg); }
private void ReceiveCompleted(ClientPeer client, SocketMsg msg) { //给应用层让其使用 //todo }