网络编程资料总结(二)----Tcp多线程服务器和客户端的实现
2009-12-02 10:08
911 查看
服务端:
第一种方法:
第二种方法:
第三种方法:
客户端:
第一种方法:
]using System; using System.IO; using System.Net.Sockets; using System.Text; using System.Collections; using System.Threading; class ClientConnectionPool { // Creates a synchronized wrapper around the Queue. private Queue SyncdQ = Queue.Synchronized( new Queue() ); public void Enqueue(ClientHandler client) { SyncdQ.Enqueue(client) ; } public ClientHandler Dequeue() { return (ClientHandler) ( SyncdQ.Dequeue() ) ; } public int Count { get { return SyncdQ.Count ; } } public object SyncRoot { get { return SyncdQ.SyncRoot ; } } } // class ClientConnectionPool class ClientService { const int NUM_OF_THREAD = 10; private ClientConnectionPool ConnectionPool ; private bool ContinueProcess = false ; private Thread [] ThreadTask = new Thread[NUM_OF_THREAD] ; public ClientService(ClientConnectionPool ConnectionPool) { this.ConnectionPool = ConnectionPool ; } public void Start() { ContinueProcess = true ; // Start threads to handle Client Task for ( int i = 0 ; i < ThreadTask.Length ; i++) { ThreadTask[i] = new Thread( new ThreadStart(this.Process) ); ThreadTask[i].Start() ; } } private void Process() { while ( ContinueProcess ) { ClientHandler client = null ; lock( ConnectionPool.SyncRoot ) { if ( ConnectionPool.Count > 0 ) client = ConnectionPool.Dequeue() ; } if ( client != null ) { client.Process() ; // Provoke client // if client still connect, schedufor later processingle it if ( client.Alive ) ConnectionPool.Enqueue(client) ; } Thread.Sleep(100) ; } } public void Stop() { ContinueProcess = false ; for ( int i = 0 ; i < ThreadTask.Length ; i++) { if ( ThreadTask[i] != null && ThreadTask[i].IsAlive ) ThreadTask[i].Join() ; } // Close all client connections while ( ConnectionPool.Count > 0 ) { ClientHandler client = ConnectionPool.Dequeue() ; client.Close() ; Console.WriteLine("Client connection is closed!") ; } } } // class ClientService public class SynchronousSocketListener { private const int portNum = 10116 ; public static void StartListening() { ClientService ClientTask ; // Client Connections Pool ClientConnectionPool ConnectionPool = new ClientConnectionPool() ; // Client Task to handle client requests ClientTask = new ClientService(ConnectionPool) ; ClientTask.Start() ; TcpListener listener = new TcpListener(portNum); try { listener.Start(); int TestingCycle = 3 ; // Number of testing cycles int ClientNbr = 0 ; // Start listening for connections. Console.WriteLine("Waiting for a connection..."); while ( TestingCycle > 0 ) { TcpClient handler = listener.AcceptTcpClient(); if ( handler != null) { Console.WriteLine("Client#{0} accepted!", ++ClientNbr) ; // An incoming connection needs to be processed. ConnectionPool.Enqueue( new ClientHandler(handler) ) ; --TestingCycle ; } else break; } listener.Stop(); // Stop client requests handling ClientTask.Stop() ; } catch (Exception e) { Console.WriteLine(e.ToString()); } Console.WriteLine("/nHit enter to continue..."); Console.Read(); } public static int Main(String[] args) { StartListening(); return 0; } } class ClientHandler { private TcpClient ClientSocket ; private NetworkStream networkStream ; bool ContinueProcess = false ; private byte[] bytes; // Data buffer for incoming data. private StringBuilder sb = new StringBuilder(); // Received data string. private string data = null; // Incoming data from the client. public ClientHandler (TcpClient ClientSocket) { ClientSocket.ReceiveTimeout = 100 ; // 100 miliseconds this.ClientSocket = ClientSocket ; networkStream = ClientSocket.GetStream(); bytes = new byte[ClientSocket.ReceiveBufferSize]; ContinueProcess = true ; } public void Process() { try { int BytesRead = networkStream.Read(bytes, 0, (int) bytes.Length); if ( BytesRead > 0 ) // There might be more data, so store the data received so far. sb.Append(Encoding.ASCII.GetString(bytes, 0, BytesRead)); else // All the data has arrived; put it in response. ProcessDataReceived() ; } catch ( IOException ) { // All the data has arrived; put it in response. ProcessDataReceived() ; } catch ( SocketException ) { networkStream.Close() ; ClientSocket.Close(); ContinueProcess = false ; Console.WriteLine( "Conection is broken!"); } } // Process() private void ProcessDataReceived() { if ( sb.Length > 0 ) { bool bQuit = ( String.Compare( sb.ToString(), "quit", true ) == 0 ) ; data = sb.ToString() ; sb.Length = 0 ; // Clear buffer Console.WriteLine( "Text received from client:") ; Console.WriteLine(data) ; StringBuilder response = new StringBuilder( ) ; response.Append( "Received at " ) ; response.Append( DateTime.Now.ToString() ) ; response.Append( "/r/n" ) ; response.Append( data ) ; // Echo the data back to the client. byte[] sendBytes = Encoding.ASCII.GetBytes(response.ToString()); networkStream.Write(sendBytes, 0, sendBytes.Length); // Client stop processing if ( bQuit ) { networkStream.Close() ; ClientSocket.Close(); ContinueProcess = false ; } } } public void Close() { networkStream.Close() ; ClientSocket.Close(); } public bool Alive { get { return ContinueProcess ; } } } // class ClientHandler
第二种方法:
]using System; using System.IO; using System.Net.Sockets; using System.Text; using System.Collections; using System.Threading; public class SynchronousSocketListener { private const int portNum = 10116 ; private static ArrayList ClientSockets ; private static bool ContinueReclaim = true; private static Thread ThreadReclaim ; public static void StartListening() { ClientSockets = new ArrayList() ; ThreadReclaim = new Thread( new ThreadStart(Reclaim) ); ThreadReclaim.Start() ; TcpListener listener = new TcpListener(portNum); try { listener.Start(); int TestingCycle = 3 ; int ClientNbr = 0 ; // Start listening for connections. Console.WriteLine("Waiting for a connection..."); while ( TestingCycle > 0 ) { TcpClient handler = listener.AcceptTcpClient(); if ( handler != null) { Console.WriteLine("Client#{0} accepted!", ++ClientNbr) ; // An incoming connection needs to be processed. lock( ClientSockets.SyncRoot ) { int i = ClientSockets.Add( new ClientHandler(handler) ) ; ((ClientHandler) ClientSockets[i]).Start() ; } --TestingCycle ; } else break; } listener.Stop(); ContinueReclaim = false ; ThreadReclaim.Join() ; foreach ( Object Client in ClientSockets ) { ( (ClientHandler) Client ).Stop() ; } } catch (Exception e) { Console.WriteLine(e.ToString()); } Console.WriteLine("/nHit enter to continue..."); Console.Read(); } private static void Reclaim() { while (ContinueReclaim) { lock( ClientSockets.SyncRoot ) { for ( int x = ClientSockets.Count-1 ; x >= 0 ; x-- ) { Object Client = ClientSockets[x] ; if ( !( ( ClientHandler ) Client ).Alive ) { ClientSockets.Remove( Client ) ; Console.WriteLine("A client left") ; } } } Thread.Sleep(200) ; } } public static int Main(String[] args) { StartListening(); return 0; } } class ClientHandler { TcpClient ClientSocket ; bool ContinueProcess = false ; Thread ClientThread ; public ClientHandler (TcpClient ClientSocket) { this.ClientSocket = ClientSocket ; } public void Start() { ContinueProcess = true ; ClientThread = new Thread ( new ThreadStart(Process) ) ; ClientThread.Start() ; } private void Process() { // Incoming data from the client. string data = null; // Data buffer for incoming data. byte[] bytes; if ( ClientSocket != null ) { NetworkStream networkStream = ClientSocket.GetStream(); ClientSocket.ReceiveTimeout = 100 ; // 1000 miliseconds while ( ContinueProcess ) { bytes = new byte[ClientSocket.ReceiveBufferSize]; try { int BytesRead = networkStream.Read(bytes, 0, (int) ClientSocket.ReceiveBufferSize); if ( BytesRead > 0 ) { data = Encoding.ASCII.GetString(bytes, 0, BytesRead); // Show the data on the console. Console.WriteLine( "Text received : {0}", data); // Echo the data back to the client. byte[] sendBytes = Encoding.ASCII.GetBytes(data); networkStream.Write(sendBytes, 0, sendBytes.Length); if ( data == "quit" ) break ; } } catch ( IOException ) { } // Timeout catch ( SocketException ) { Console.WriteLine( "Conection is broken!"); break ; } Thread.Sleep(200) ; } // while ( ContinueProcess ) networkStream.Close() ; ClientSocket.Close(); } } // Process() public void Stop() { ContinueProcess = false ; if ( ClientThread != null && ClientThread.IsAlive ) ClientThread.Join() ; } public bool Alive { get { return ( ClientThread != null && ClientThread.IsAlive ); } } } // class ClientHandler
第三种方法:
]using System; using System.IO; using System.Net.Sockets; using System.Text; using System.Collections; using System.Threading; class SharedState { public bool ContinueProcess ; public int NumberOfClients ; public AutoResetEvent Ev ; } public class SynchronousSocketListener { private const int portNum = 10116 ; private static SharedState SharedStateObj ; public static void StartListening() { SharedStateObj = new SharedState() ; SharedStateObj.ContinueProcess = true ; SharedStateObj.NumberOfClients = 0 ; SharedStateObj.Ev = new AutoResetEvent(false) ; TcpListener listener = new TcpListener(portNum); try { listener.Start(); int TestingCycle = 3 ; int ClientNbr = 0 ; // Start listening for connections. Console.WriteLine("Waiting for a connection..."); while ( TestingCycle > 0 ) { TcpClient handler = listener.AcceptTcpClient(); if ( handler != null) { Console.WriteLine("Client#{0} accepted!", ++ClientNbr) ; // An incoming connection needs to be processed. ClientHandler client = new ClientHandler(handler) ; // Add no. of clients by one Interlocked.Increment(ref SharedStateObj.NumberOfClients ); // Queue client handling task to thread pool ThreadPool.QueueUserWorkItem(new WaitCallback(client.Process), SharedStateObj); --TestingCycle ; } else break; } listener.Stop(); } catch (Exception e) { Console.WriteLine(e.ToString()); } // Stop and wait all client connections to end SharedStateObj.ContinueProcess = false ; SharedStateObj.Ev.WaitOne() ; Console.WriteLine("/nHit enter to continue..."); Console.Read(); } public static int Main(String[] args) { StartListening(); return 0; } } class ClientHandler { private TcpClient ClientSocket ; public ClientHandler (TcpClient ClientSocket) { this.ClientSocket = ClientSocket ; } public void Process(Object O) { SharedState SharedStateObj = (SharedState) O ; // Incoming data from the client. string data = null; bool bQuit = false ; // Data buffer for incoming data. byte[] bytes; NetworkStream networkStream = ClientSocket.GetStream(); ClientSocket.ReceiveTimeout = 100 ; // 1000 miliseconds bytes = new byte[ClientSocket.ReceiveBufferSize]; try { int BytesRead = networkStream.Read(bytes, 0, (int) ClientSocket.ReceiveBufferSize); if ( BytesRead > 0 ) { data = Encoding.ASCII.GetString(bytes, 0, BytesRead); // Show the data on the console. Console.WriteLine( "Text received : {0}", data); // Echo the data back to the client. byte[] sendBytes = Encoding.ASCII.GetBytes(data); networkStream.Write(sendBytes, 0, sendBytes.Length); bQuit = ( String.Compare( data, "quit", true ) == 0 ) ; } } catch ( IOException ) { } // Timeout catch ( SocketException ) { bQuit = true ; Console.WriteLine( "Conection is broken!"); } // Schedule task again if ( SharedStateObj.ContinueProcess && !bQuit ) ThreadPool.QueueUserWorkItem(new WaitCallback(this.Process), SharedStateObj); else { networkStream.Close() ; ClientSocket.Close(); // Deduct no. of clients by one Interlocked.Decrement(ref SharedStateObj.NumberOfClients ); Console.WriteLine("A client left, number of connections is {0}", SharedStateObj.NumberOfClients) ; } // Signal main process if this is the last client connections main thread requested to stop. if ( !SharedStateObj.ContinueProcess && SharedStateObj.NumberOfClients == 0 ) SharedStateObj.Ev.Set(); } // Process() } // class ClientHandler
客户端:
]using System; using System.Net.Sockets; using System.Text; class TcpClientTest { private const int portNum = 10116 ; static public void Main() { TcpClient tcpClient = new TcpClient(); try{ tcpClient.Connect("localhost", portNum); NetworkStream networkStream = tcpClient.GetStream(); if (networkStream.CanWrite && networkStream.CanRead){ String DataToSend = "" ; while ( DataToSend != "quit" ) { Console.WriteLine("/nType a text to be sent:"); DataToSend = Console.ReadLine() ; if ( DataToSend.Length == 0 ) break ; Byte[] sendBytes = Encoding.ASCII.GetBytes(DataToSend); networkStream.Write(sendBytes, 0, sendBytes.Length); // Reads the NetworkStream into a byte buffer. byte[] bytes = new byte[tcpClient.ReceiveBufferSize]; int BytesRead = networkStream.Read(bytes, 0, (int) tcpClient.ReceiveBufferSize); // Returns the data received from the host to the console. string returndata = Encoding.ASCII.GetString(bytes, 0 , BytesRead); Console.WriteLine("This is what the host returned to you: /r/n{0}", returndata); } networkStream.Close(); tcpClient.Close(); } else if (!networkStream.CanRead){ Console.WriteLine("You can not write data to this stream"); tcpClient.Close(); } else if (!networkStream.CanWrite){ Console.WriteLine("You can not read data from this stream"); tcpClient.Close(); } } catch (SocketException) { Console.WriteLine("Sever not available!"); } catch (System.IO.IOException) { Console.WriteLine("Sever not available!"); } catch (Exception e ) { Console.WriteLine(e.ToString()); } } // Main() } // class TcpClientTest {
相关文章推荐
- Java基础知识强化之网络编程笔记14:TCP之多个客户端上传到一个服务器的思考(多线程改进)
- TCP网络编程中多线程的客户端实现(linux下)
- Linux网络编程 之 TCP 多线程的服务器和客户端同时收发数据
- WINDOWS (服务器) 和 DOS(客户端) 网络互连 基于TCP/IP的编程实现
- C# 网络编程之Tcp实现客户端和服务器聊天
- WINDOWS (服务器) 和 DOS(客户端) 网络互连 基于TCP/IP的编程实现
- Linux网络编程--多线程实现echo服务器与客户端“一对多”功能,网络编程的“Hello World!” - 壮壮熊
- WINDOWS (服务器) 和 DOS(客户端) 网络互连 基于TCP/IP的编程实现
- WINDOWS (服务器) 和 DOS(客户端) 网络互连 基于TCP/IP的编程实现
- WINDOWS (服务器) 和 DOS(客户端) 网络互连 基于TCP/IP的编程实现
- Linux网络编程--多线程实现echo服务器与客户端“一对多”功能,是网络编程的“Hello World!”
- WINDOWS (服务器) 和 DOS(客户端) 网络互连 基于TCP/IP的编程实现
- WINDOWS (服务器) 和 DOS(客户端) 网络互连 基于TCP/IP的编程实现
- linux网络编程--服务器客户端(TCP实现)
- WINDOWS (服务器) 和 DOS(客户端) 网络互连 基于TCP/IP的编程实现
- iOS网络编程实践–NSStream实现TCP Socket iPhone客户端
- Java基础知识强化之网络编程笔记07:TCP之服务器给客户端一个反馈案例
- 2015/12/14 Python网络编程,TCP/IP客户端和服务器初探
- Linux 网络编程基础(一) ---------------客户端/服务器的简单实现
- iOS网络编程实践--NSStream实现TCP Socket iPhone客户端