protected static void SendCallback(IAsyncResult ar) { AbstractTcpSocketClientHandler handler = null; try { SocketError errorCode = SocketError.Success; // Retrieve the socket from the state object. handler = (AbstractTcpSocketClientHandler)ar.AsyncState; // Complete sending the data to the remote device. int bytesSent = handler.socket.EndSend(ar, out errorCode); Trace.WriteLine(string.Format("Complete asynch send. Byte {0} sent.", bytesSent)); } catch (SocketException sex) { Trace.WriteLine(string.Format("Socket error, the connection will be closed. Error {0} : {1} : {2}", sex.ErrorCode, sex.SocketErrorCode, sex.Message)); handler.OnCloseConnection(handler); } catch (Exception ex) { Trace.WriteLine(string.Format("Exception during asynch send {0}", ex)); } finally { // Signal that all bytes have been sent. handler.sendDone.Set(); } }
public virtual ClientInfo this[AbstractTcpSocketClientHandler abstractTcpSocketClientHandler] { get { return this.clientList[abstractTcpSocketClientHandler]; } }
void Server_DataReceived(SocketServerLib.SocketHandler.AbstractTcpSocketClientHandler handler, SocketServerLib.Message.AbstractMessage message) { if (DataReceived != null) { DataReceived(handler.GetHashCode().ToString(), message.GetBuffer()); } }
/// <summary> /// Raise a received message event. This method is running in the same thread of the caller. /// </summary> /// <param name="stateObj">The socket client handler closed</param> private void RaiseCloseConnectionEvent(object stateObj) { if (closeConnectionEvent != null) { AbstractTcpSocketClientHandler closedHandler = (AbstractTcpSocketClientHandler)stateObj; closeConnectionEvent(closedHandler); } }
/// <summary> /// Dispose the client. /// </summary> public void Dispose() { if (this.abstractTcpSocketClientHandler == null) { return; } this.abstractTcpSocketClientHandler.Dispose(); this.abstractTcpSocketClientHandler = null; }
/// <summary> /// Get from the client list the Client Info connected to the specific socket client handler. /// </summary> /// <param name="abstractTcpSocketClientHandler">The socket client handler to find</param> /// <returns>The client info of the socket client handler</returns> public virtual ClientInfo this[AbstractTcpSocketClientHandler abstractTcpSocketClientHandler] { get { lock (this) { if (!this.clientList.ContainsKey(abstractTcpSocketClientHandler)) { return null; } return (ClientInfo)this.clientList[abstractTcpSocketClientHandler]; } } }
void server_ReceiveMessageEvent(SocketServerLib.SocketHandler.AbstractTcpSocketClientHandler handler, SocketServerLib.Message.AbstractMessage message) { BasicMessage receivedMessage = (BasicMessage)message; byte[] buffer = receivedMessage.GetBuffer(); if (buffer.Length > 1000) { MessageBox.Show(string.Format("Received a long message of {0} bytes", receivedMessage.MessageLength), "Socket Server", MessageBoxButtons.OK, MessageBoxIcon.Information); return; } string s = System.Text.ASCIIEncoding.Unicode.GetString(buffer); this.SetReceivedText(s); }
/// <summary> /// Send a buffer. It's a synchronous operation. The previous send has to be completed. /// You can define a timeout on the previous send and skip this one in case of time out. /// </summary> /// <param name="clientHandler">The socket client handler for send</param> /// <param name="byteData">The buffer to send</param> /// <param name="previousSendTimeout">Timeout on the previous send in ms</param> /// <returns>True if the message has been sent, otherwise false</returns> private static bool SendBuffer(AbstractTcpSocketClientHandler clientHandler, byte[] byteData, int previousSendTimeout) { bool ret = false; bool flagRaiseDisconnection = false; bool flagReset = true; try { // Check if client is connected if (!clientHandler.socket.Connected) { throw new TcpSocketException("Client disconnected", true); } // Wait for previous send if (previousSendTimeout != 0) { if (!clientHandler.sendWaitHandle.WaitOne(previousSendTimeout)) { throw new TcpSocketException("Send skip for timeout"); } } else { clientHandler.sendWaitHandle.WaitOne(); } // Sending the data to the remote device. Trace.WriteLine(string.Format("Sending {0} bytes", byteData.Length)); int n = clientHandler.socket.Send(byteData); if (n != byteData.Length) { Trace.WriteLine(string.Format("Invalid send: sent {0} bytes on {1} bytes", n, byteData.Length)); throw new TcpSocketException("Invalid send"); } ret = true; } catch (SocketException sex) { Trace.WriteLine(string.Format("Exception {0}. Connection will be closed", sex)); flagRaiseDisconnection = true; } catch (TcpSocketException netEx) { Trace.WriteLine(string.Format("Exception {0}. Connection will be closed", netEx)); if (netEx.DisconnectionRequired) { flagRaiseDisconnection = true; } // Not release the sendwaithandle in case of send timeout else { flagReset = false; } } catch (ObjectDisposedException dex) { Trace.WriteLine(string.Format("Exception {0}. Connection will be closed", dex)); flagRaiseDisconnection = true; } catch (Exception ex) { Trace.WriteLine(string.Format("Exception {0}.", ex)); } finally { if (flagReset) { Trace.WriteLine("release sendwaithandle"); clientHandler.sendWaitHandle.Set(); } if (flagRaiseDisconnection) { Trace.WriteLine("Client will be disconnected."); clientHandler.OnCloseConnection(clientHandler); } } return ret; }
/// <summary> /// Handle a close connection. A close connection event is raise but in a new thread in order to not block the main thread. /// Override this method to change the behavior. /// </summary> /// <param name="closedHandler">The socket client handler closed</param> protected virtual void OnCloseConnection(AbstractTcpSocketClientHandler closedHandler) { ThreadPool.QueueUserWorkItem(new WaitCallback(closedHandler.RaiseCloseConnectionEvent), closedHandler); }
/// <summary> /// Send a buffer. It's a synchronous operation. The previous send has to be completed. /// You can define a timeout on the previous send and skip this one in case of time out. /// </summary> /// <param name="clientHandler">The socket client handler for send</param> /// <param name="byteData">The buffer to send</param> /// <param name="previousSendTimeout">Timeout on the previous send in ms</param> /// <returns>True if the message has been sent, otherwise false</returns> private static bool SendBuffer(AbstractTcpSocketClientHandler clientHandler, byte[] byteData, int previousSendTimeout) { bool ret = false; bool flagRaiseDisconnection = false; bool flagReset = true; try { // Check if client is connected if (!clientHandler.socket.Connected) { throw new TcpSocketException("Client disconnected", true); } // Wait for previous send if (previousSendTimeout != 0) { if (!clientHandler.sendWaitHandle.WaitOne(previousSendTimeout)) { throw new TcpSocketException("Send skip for timeout"); } } else { clientHandler.sendWaitHandle.WaitOne(); } // Sending the data to the remote device. Trace.WriteLine(string.Format("Sending {0} bytes", byteData.Length)); int n = clientHandler.socket.Send(byteData); if (n != byteData.Length) { Trace.WriteLine(string.Format("Invalid send: sent {0} bytes on {1} bytes", n, byteData.Length)); throw new TcpSocketException("Invalid send"); } ret = true; } catch (SocketException sex) { Trace.WriteLine(string.Format("Exception {0}. Connection will be closed", sex)); flagRaiseDisconnection = true; } catch (TcpSocketException netEx) { Trace.WriteLine(string.Format("Exception {0}. Connection will be closed", netEx)); if (netEx.DisconnectionRequired) { flagRaiseDisconnection = true; } // Not release the sendwaithandle in case of send timeout else { flagReset = false; } } catch (ObjectDisposedException dex) { Trace.WriteLine(string.Format("Exception {0}. Connection will be closed", dex)); flagRaiseDisconnection = true; } catch (Exception ex) { Trace.WriteLine(string.Format("Exception {0}.", ex)); } finally { if (flagReset) { Trace.WriteLine("release sendwaithandle"); clientHandler.sendWaitHandle.Set(); } if (flagRaiseDisconnection) { Trace.WriteLine("Client will be disconnected."); clientHandler.OnCloseConnection(clientHandler); } } return(ret); }
/// <summary> /// Connect the client to the EndPoint on SSL. /// </summary> /// <param name="endPoint">The remote end point</param> /// <param name="clientCertificatePath">The client certificate file</param> /// <param name="certificatePassword">The client certifciate password</param> public void Connect(IPEndPoint endPoint, string clientCertificatePath, string certificatePassword) { // Load the client certificte X509Certificate2 clientCertificate = new X509Certificate2(clientCertificatePath, certificatePassword); X509CertificateCollection clientCertificateList = new X509CertificateCollection(); clientCertificateList.Add(clientCertificate); // Connect the client to the remote end point TcpClient sslTcpClient = new TcpClient(); sslTcpClient.Connect(endPoint); sslTcpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, this.KeepAlive); // Open a ssl stream for the communication SslStream sslStream = new SslStream(sslTcpClient.GetStream(), false, new RemoteCertificateValidationCallback(this.OnVerifyCertificate)); sslStream.AuthenticateAsClient("NONE", clientCertificateList, SslProtocols.Ssl3, false); //TODO: params from config for mutual auth, protocol and revocation // Create the socket client handler, add the callback for the event and start to receiving Socket client = sslTcpClient.Client; client.Blocking = true; handler = GetHandler(client, sslStream); handler.ReceiveMessageEvent += new ReceiveMessageDelegate(handler_ReceiveMessageEvent); handler.CloseConnectionEvent += new SocketConnectionDelegate(handler_CloseConnectionEvent); handler.InReceivingEvent += new SocketConnectionDelegate(handler_InReceivingEvent); connected = true; this.OnConnection(handler); handler.StartReceive(); }
/// <summary> /// Callback for asynchronous receiving. /// </summary> /// <param name="ar">The socket state object for receiving data</param> protected static void ReadCallback(IAsyncResult ar) { SocketStateObject state = (SocketStateObject)ar.AsyncState; AbstractTcpSocketClientHandler handler = state.workHandler; try { // Read data from the client socket. int read = handler.EndReceive(ar); Trace.WriteLine(string.Format("Receive {0} bytes", read)); // Data was read from the client socket. if (read > 0) { // Fire event for incoming message handler.OnReceivingMessage(handler); while (true) { AbstractMessage message = AbstractMessage.TryReadMessage(handler.GetMessageInstance(), state, read); // Fire event for received message if (message != null) { ReceiveMessageStateObject rcvObj = new ReceiveMessageStateObject() { Handler = handler, Message = message }; handler.OnReceiveMessage(rcvObj); } if (state.pendingBuffer == null) { break; } read = 0; } handler.socket.BeginReceive(state, new AsyncCallback(ReadCallback)); } else { handler.Close(); } } catch (MessageException mex) { // Invalid message Trace.WriteLine(string.Format("Exception {0}. Connection will be closed", mex)); state.message = null; state.pendingBuffer = null; handler.Close(); } catch (SocketException sex) { if (sex.SocketErrorCode == SocketError.ConnectionReset || sex.SocketErrorCode == SocketError.ConnectionAborted) { Trace.WriteLine(string.Format("Socket error for disconnection {0} : {1} : {2}. Client will be disconnected", sex.ErrorCode, sex.SocketErrorCode, sex.Message)); state.message = null; state.pendingBuffer = null; handler.Close(); } else { Trace.WriteLine(string.Format("Exception {0}. Connection will be closed", sex)); state.message = null; state.pendingBuffer = null; handler.Close(); } } catch (Exception ex) { Trace.WriteLine(string.Format("Exception {0}. Connection will be closed", ex)); state.message = null; state.pendingBuffer = null; handler.Close(); } }
/// <summary> /// Start the asynchronous sending data /// </summary> /// <param name="buffer">The buffer to send</param> /// <param name="handler">The socket client handler</param> /// <param name="callback">The callback for the asynchronous sending</param> internal virtual void BeginSend(byte[] buffer, AbstractTcpSocketClientHandler handler, AsyncCallback callback) { this.socket.BeginSend(buffer, 0, buffer.Length, 0, callback, handler); }
/// <summary> /// Raise an incoming message event. /// </summary> /// <param name="handler">The socket client handler of the close connection</param> void handler_InReceivingEvent(AbstractTcpSocketClientHandler handler) { if (inReceivingEvent != null) { inReceivingEvent(handler); } }
/// <summary> /// Raise the receive message event. /// </summary> /// <param name="handler">The socket client handler for the received message</param> /// <param name="abstractMessage">The message received</param> protected virtual void OnReceiveMessage(AbstractTcpSocketClientHandler handler, AbstractMessage abstractMessage) { if (receiveMessageEvent != null) { receiveMessageEvent(handler, abstractMessage); } }
/// <summary> /// Connect the client to the EndPoint. /// </summary> /// <param name="endPoint">The remote end point</param> public void Connect(IPEndPoint endPoint) { // Connect the client to the remote end point Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, this.KeepAlive); client.Connect(endPoint); client.Blocking = true; // Create the socket client handler, add the callback for the event and start to receiving handler = GetHandler(client, null); handler.ReceiveMessageEvent += new ReceiveMessageDelegate(handler_ReceiveMessageEvent); handler.CloseConnectionEvent += new SocketConnectionDelegate(handler_CloseConnectionEvent); handler.InReceivingEvent += new SocketConnectionDelegate(handler_InReceivingEvent); connected = true; this.OnConnection(handler); handler.StartReceive(); //((IPEndPoint)client.LocalEndPoint).Port }
/// <summary> /// Constructor. /// </summary> /// <param name="abstractTcpSocketClientHandler">The socket client handler</param> public ClientInfo(AbstractTcpSocketClientHandler abstractTcpSocketClientHandler) { this.abstractTcpSocketClientHandler = abstractTcpSocketClientHandler; this.clientUID = this.abstractTcpSocketClientHandler.ToString(); }
/// <summary> /// Close and dispose the client. /// </summary> public void Dispose() { if (handler != null) { handler.Close(); handler.Dispose(); handler = null; } }
/// <summary> /// Raise a received message event. /// </summary> /// <param name="handler">The socket client handler of the close connection</param> /// <param name="message">The message received</param> void handler_ReceiveMessageEvent(AbstractTcpSocketClientHandler handler, AbstractMessage message) { OnReceiveMessage(handler, message); }
/// <summary> /// Override this method to change the instace used for the Client Info /// </summary> /// <param name="abstractTcpSocketClientHandler">The socket client handler for the cient info</param> /// <returns>The client info contains the socket clilent handler</returns> protected virtual ClientInfo GetClientInfo(AbstractTcpSocketClientHandler abstractTcpSocketClientHandler) { return new ClientInfo(abstractTcpSocketClientHandler); }
/// <summary> /// Handle a close connection. A close connection event is raise but in a new thread in order to not block the main thread. /// Override this method to change the behavior. /// </summary> /// <param name="closedHandler">The socket client handler closed</param> protected virtual void OnCloseConnection(AbstractTcpSocketClientHandler closedHandler) { ThreadPool.QueueUserWorkItem(new WaitCallback(closedHandler.RaiseCloseConnectionEvent), closedHandler); }
/// <summary> /// Raise the close connection event. /// </summary> /// <param name="handler">The socket client handler disconnected</param> protected virtual void clientHandler_CloseConnectionEvent(AbstractTcpSocketClientHandler handler) { clientList.RemoveClient(clientList[handler]); if (closeConnectionEvent != null) { closeConnectionEvent(handler); } }
/// <summary> /// Raise a close connection event. /// </summary> /// <param name="handler">The socket client handler of the close connection</param> void handler_CloseConnectionEvent(AbstractTcpSocketClientHandler handler) { connected = false; if (closeConnectionEvent != null) { closeConnectionEvent(handler); } }
/// <summary> /// Raise the new conection event. /// </summary> /// <param name="handler">The socket client handler connected</param> protected virtual void OnConnection(AbstractTcpSocketClientHandler handler) { if (connectionEvent != null) { connectionEvent(handler); } }
private void server_CloseConnectionEvent(AbstractTcpSocketClientHandler handler) { ServerConsoleListBox.Items.Add("Client disconnected.."); }
/// <summary> /// Start the asynchronous sending data /// </summary> /// <param name="buffer">The buffer to send</param> /// <param name="handler">The socket client handler</param> /// <param name="callback">The callback for the asynchronous sending</param> internal virtual void BeginSend(byte[] buffer, AbstractTcpSocketClientHandler handler, AsyncCallback callback) { this.socket.BeginSend(buffer, 0, buffer.Length, 0, callback, handler); }
private void server_ConnectionEvent(AbstractTcpSocketClientHandler handler) { ClientInfo[] clientList = this.server.GetClientList(); OnlinePlayersListBox.Items.Add("Client " + clientList[clientList.Length].ClientUID); ServerConsoleListBox.Items.Add("Client " + clientList[clientList.Length].ClientUID + " connected.."); }