您的位置:首页 > 理论基础 > 计算机网络

网络编程资料总结(二)----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 {
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐