I want the TCP server to keep a constant connection with the client. Now, after the client connects, he receives one message and sends one reply and receives nothing more from the client.
Code:
using Server.Models; using Server.Models.HTTP; using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Sockets; using System.Reflection; using System.Text; using System.Threading; namespace Server { public class Server { private readonly int m_numConnections; private readonly int m_receiveBufferSize; BufferManager m_bufferManager; const int opsToPreAlloc = 2; Socket listenSocket; SocketAsyncEventArgsPool m_readWritePool; int m_totalBytesRead; int m_numConnectedSockets; Semaphore m_maxNumberAcceptedClients; public Server(int numConnections, int receiveBufferSize) { m_totalBytesRead = 0; m_numConnectedSockets = 0; m_numConnections = numConnections; m_receiveBufferSize = receiveBufferSize; m_bufferManager = new BufferManager(receiveBufferSize * numConnections * opsToPreAlloc, receiveBufferSize); m_readWritePool = new SocketAsyncEventArgsPool(numConnections); m_maxNumberAcceptedClients = new Semaphore(numConnections, numConnections); } public void Init() { m_bufferManager.InitBuffer(); SocketAsyncEventArgs readWriteEventArg; for (int i = 0; i < m_numConnections; i++) { readWriteEventArg = new SocketAsyncEventArgs(); readWriteEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(IO_Completed); readWriteEventArg.UserToken = new AsyncUserToken(); m_bufferManager.SetBuffer(readWriteEventArg); m_readWritePool.Push(readWriteEventArg); } } public void Start(IPEndPoint localEndPoint) { listenSocket = new Socket(localEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp); listenSocket.Bind(localEndPoint); listenSocket.Listen(100); StartAccept(null); Console.WriteLine("Press any key to terminate the server process...."); Console.ReadKey(); } public void StartAccept(SocketAsyncEventArgs acceptEventArg) { if(acceptEventArg == null) { acceptEventArg = new SocketAsyncEventArgs(); acceptEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(AcceptEventArg_Completed); } else { acceptEventArg.AcceptSocket = null; } m_maxNumberAcceptedClients.WaitOne(); bool willRaiseEvent = listenSocket.AcceptAsync(acceptEventArg); if(!willRaiseEvent) { ProcessAccept(acceptEventArg); } } void AcceptEventArg_Completed(object sender, SocketAsyncEventArgs e) { ProcessAccept(e); } private void ProcessAccept(SocketAsyncEventArgs e) { Interlocked.Increment(ref m_numConnectedSockets); Console.WriteLine("Client connection accepted. There are {0} clients connected to the server", m_numConnectedSockets); SocketAsyncEventArgs readEventArgs = m_readWritePool.Pop(); ((AsyncUserToken)readEventArgs.UserToken).Socket = e.AcceptSocket; bool willRaiseEvent = e.AcceptSocket.ReceiveAsync(readEventArgs); if(!willRaiseEvent) { ProcessReceive(readEventArgs); } StartAccept(e); } void IO_Completed(object sender, SocketAsyncEventArgs e) { switch(e.LastOperation) { case SocketAsyncOperation.Receive: ProcessReceive(e); break; case SocketAsyncOperation.Send: ProcessSend(e); break; default: throw new ArgumentException("The last operation completed on the socket was not a receive or send"); } } public bool HasMethod(object objectToCheck, string methodName) { var type = objectToCheck.GetType(); return type.GetMethod(methodName) != null; } private void ProcessReceive(SocketAsyncEventArgs e) { AsyncUserToken token = (AsyncUserToken)e.UserToken; if (e.BytesTransferred > 0 && e.SocketError == SocketError.Success) { Interlocked.Add(ref m_totalBytesRead, e.BytesTransferred); e.SetBuffer(e.Offset, e.BytesTransferred); bool willRaiseEvent = token.Socket.SendAsync(e); if(!willRaiseEvent) { ProcessSend(e); } } } private void ProcessSend(SocketAsyncEventArgs e) { if (e.SocketError == SocketError.Success) { AsyncUserToken token = (AsyncUserToken)e.UserToken; bool willRaiseEvent = token.Socket.ReceiveAsync(e); if (!willRaiseEvent) { ProcessReceive(e); } } else { CloseClientSocket(e); } } private void CloseClientSocket(SocketAsyncEventArgs e) { AsyncUserToken token = e.UserToken as AsyncUserToken; try { token.Socket.Shutdown(SocketShutdown.Send); } catch (Exception) { } token.Socket.Close(); Interlocked.Decrement(ref m_numConnectedSockets); m_readWritePool.Push(e); m_maxNumberAcceptedClients.Release(); Console.WriteLine("A client has been disconnected from the server. There are {0} clients connected to the server", m_numConnectedSockets); } } }
когда я убираю CloseSocket- this method is not in your code - tym32167