Socket的使用

要通过互联网进行通信,至少需要一对Socket,其中一个为ClientSocket客户端使用,另一个ServerSocket服务器端使用,两Socket连接过程分三步骤:
1)服务器监听Listening;ServerSocket并不定位具体的客户端Socket,而是处于等待连接状态,实时监控网络状态。
2)客户端请求Request;ClientSocket发出连接请求(Connect Request),要连接的目标是服务器端的Socket。ClientSocket首先必须描述它要连接的ServerSocket,指出ServerSocket的地址(如IPv4或IPv6)和端口号Port,然后就向ServerSocket发出连接请求。
3)连接确认;当ServerSocket监听到或者接收到ClientSocket的连接请求,它就响应ClientSocket的请求,建立一个新的线程来处理此请求,然后把ServerSocket的描述发给客户端,一旦客户端确认了此描述,连接就成功建立。而ServerClient继续处于监听状态,继续接收其他ClientSocket的连接请求(因为每次请求都是交给新线程来处理的)。

.Net中Socket的命名空间:System.Net.Sockets
网络协议的命名空间:System.Net

以下是一些例子:
(1)利用Socket发送一个Http请求:
这里只使用到一个ClientSocket;主要反应了三步骤中的第(2)(3)两步骤;SeverSocket由Web服务器来扮演。
ContractedBlock.gif ExpandedBlockStart.gif HttpGetRequest
None.gifpublic static string HttpGetRequest(string url)
ExpandedBlockStart.gifContractedBlock.gif        
dot.gif
InBlock.gif            
//set request data
InBlock.gif
            Encoding ASCII = Encoding.ASCII;
InBlock.gif            
string getRequest = "GET / HTTP/1.1\r\nHost: " + url + "\r\nConnection: Close\r\n\r\n";
InBlock.gif            
//Convert request string to bytes
InBlock.gif
            byte[] requestBytes = ASCII.GetBytes(getRequest);
InBlock.gif            
//set recvice buffer size as 256 bytes
InBlock.gif
            byte[] recvBytes = new byte[256];
InBlock.gif            
// the return page 
InBlock.gif
            string recvicePageHtml = "";
InBlock.gif            
//IPAddress is the IP address and IPEndPoint is the Port
InBlock.gif            
//using the DNS to get the first IP Address
InBlock.gif
            IPHostEntry host;
InBlock.gif            IPAddress hostIP;
InBlock.gif            IPEndPoint hostPort;
InBlock.gif            
try
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                host 
= Dns.GetHostEntry(url);
InBlock.gif                hostIP 
= host.AddressList[0];
InBlock.gif                hostPort 
= new IPEndPoint(hostIP, 80);
ExpandedSubBlockEnd.gif            }

InBlock.gif            
catch(Exception e)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                recvicePageHtml 
= e.Message;
InBlock.gif                
return recvicePageHtml;
ExpandedSubBlockEnd.gif            }

InBlock.gif            
InBlock.gif            
InBlock.gif            
//Create the Client Socket use TCP and Stream to send the http request
InBlock.gif
            Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
InBlock.gif            
//send the Connect Request, if connect success, then continue
InBlock.gif
            clientSocket.Connect(hostPort);
InBlock.gif            
if (!clientSocket.Connected)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                recvicePageHtml 
= "Unable to get the Web";
InBlock.gif                
return recvicePageHtml;
ExpandedSubBlockEnd.gif            }

InBlock.gif            
//send the Http Get Reqeust
InBlock.gif
            clientSocket.Send(requestBytes, requestBytes.Length, SocketFlags.None);
InBlock.gif            Single totalSize 
= 0;
InBlock.gif            
int recvDataSize = clientSocket.Receive(recvBytes, recvBytes.Length, SocketFlags.None);
InBlock.gif            recvicePageHtml 
= "Default Html Page on [" + host.HostName + ":" + host.AddressList[0+ "]:\r\n\r\n";
InBlock.gif            recvicePageHtml 
+= ASCII.GetString(recvBytes, 0, recvDataSize);
InBlock.gif
InBlock.gif            
while (recvDataSize > 0)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                totalSize 
+= recvDataSize;
InBlock.gif                recvDataSize 
= clientSocket.Receive(recvBytes, recvBytes.Length, SocketFlags.None);
InBlock.gif                recvicePageHtml 
+= ASCII.GetString(recvBytes, 0, recvDataSize);
ExpandedSubBlockEnd.gif            }

InBlock.gif            recvicePageHtml 
+= "\r\n\r\nTotal Recvice " + totalSize + " bytes";
InBlock.gif            
return recvicePageHtml;
ExpandedBlockEnd.gif        }

ContractedBlock.gif ExpandedBlockStart.gif Main
None.gifstatic void Main(string[] args)
ExpandedBlockStart.gifContractedBlock.gif        
dot.gif{
InBlock.gif            
//Console.Write(HttpGetRequest("www.gdut.edu.cn"));
InBlock.gif            
//Console.Write(HttpGetRequest("www.net4.com.cn"));
InBlock.gif            
//Console.Write(HttpGetRequest("ftp.net42.com.cn"));
InBlock.gif
            Console.Write(HttpGetRequest("192.168.0.1"));
InBlock.gif            Console.Read();
ExpandedBlockEnd.gif        }
测试如下:


(2)基于C/S架构的同步Socket示例
在这里可以看到ServerSocket和ClientSocket的演示,并完全体现三个步骤(1)(2)(3)中.Net中的实现。
同步方式主要使用:Accept、Receive、Send三个同步方法。
同步方式:发送方发送数据包后,不等待接收方响应就立即接着发送下一个数据包。
使用此方式,Client或Server执行Socket连接、接收、发送操作时,Client或Server会中止工作,处于暂停状态。编程较简单,当对于需要网络操作比较繁重的时候并不太适合,此时需要采用异步方式。

1)对于Server的同步方式,在连接请求到来之前,ServerSocket一直处于Listen状态,而服务器则处于中止等待状态;当连接请求到来后,ServerSocket调用Accept方法,返回一个与ClientSocket相连的Socket处理此请求。直到请求完成后ServerSocket才继续监听等待。因为同步方式只使用一个线程来处理监听请求和响应请求。
ContractedBlock.gif ExpandedBlockStart.gif SyncServerDemo
None.gifusing System;
None.gif
using System.Collections.Generic;
None.gif
using System.Text;
None.gif
using System.Net;
None.gif
using System.Net.Sockets;
None.gif
None.gif
namespace SyncServerDemo
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif    
class SyncServer
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
static void Main(string[] args)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            Listening();
ExpandedSubBlockEnd.gif        }

InBlock.gif        
public static void Listening()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
//设置缓冲区1024字节
InBlock.gif
            byte[] buffer = new byte[10];
InBlock.gif            
//初始化ServerSocket
InBlock.gif
            IPHostEntry serverHost = Dns.GetHostEntry(Dns.GetHostName());
InBlock.gif            IPAddress serverIP 
= serverHost.AddressList[0];
InBlock.gif            IPEndPoint serverPort 
= new IPEndPoint(serverIP, 11010); //端口号按实际设置
InBlock.gif
            Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
InBlock.gif
InBlock.gif            
//将ServerSocket绑定到本地
InBlock.gif
            try
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                serverSocket.Bind(serverPort);
InBlock.gif                
//开始监听,并设置最大连接队列为10
InBlock.gif
                serverSocket.Listen(2);
InBlock.gif                
while (true)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    Console.WriteLine(
"Waiting for your connetiondot.gif");
InBlock.gif                    
//此时Listenling线程将暂停等待,直到有连接请求的到来
InBlock.gif
                    Socket handler = serverSocket.Accept();
InBlock.gif                    
string receiveData = "";
InBlock.gif                    Single dataTotalSize 
= 0;
InBlock.gif                    
int dataSize = handler.Receive(buffer);
InBlock.gif                    receiveData 
+= Encoding.ASCII.GetString(buffer, 0, dataSize);
InBlock.gif                    dataTotalSize 
+= dataSize;
InBlock.gif                    
InBlock.gif                    
//处理此请求
InBlock.gif
                    while (dataSize > 0 && handler.Available > 0)
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
dot.gif{
InBlock.gif                        dataSize 
= handler.Receive(buffer);
InBlock.gif                        receiveData 
+= Encoding.ASCII.GetString(buffer, 0, dataSize);
InBlock.gif                        dataTotalSize 
+= dataSize;
ExpandedSubBlockEnd.gif                    }

InBlock.gif                    
//显示接收到的请求数据
InBlock.gif
                    Console.WriteLine("Received data [size:{1} bytes] from [{2}]: \r\n {0}", receiveData, dataTotalSize, handler.RemoteEndPoint.ToString());
InBlock.gif                    
//将接收到的数据和数据大小返回给Client
InBlock.gif
                    byte[] returnBytes = Encoding.ASCII.GetBytes(receiveData + "\r\nDataSize: " + dataTotalSize);
InBlock.gif                    handler.Send(returnBytes);
InBlock.gif                    handler.Shutdown(SocketShutdown.Both);
InBlock.gif                    handler.Close();
ExpandedSubBlockEnd.gif                }

ExpandedSubBlockEnd.gif            }

InBlock.gif            
catch (Exception e)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                Console.WriteLine(e.ToString());
ExpandedSubBlockEnd.gif            }

InBlock.gif            Console.WriteLine(
"\nHit any key to continuedot.gif");
InBlock.gif            Console.Read();
ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

None.gif

2)Client的同步方式,ClientSocket负责发出连接请求和请求数据,并接收返回的数据。同样是在单线程中处理请求和处理返回数据。
ContractedBlock.gif ExpandedBlockStart.gif SyncClientDemo
None.gifusing System;
None.gif
using System.Collections.Generic;
None.gif
using System.Text;
None.gif
using System.Net;
None.gif
using System.Net.Sockets;
None.gif
None.gif
namespace SyncClientDemo
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif    
class SyncClient
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
static void Main(string[] args)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
//SyncRequest("127.0.0.1", "Test");
InBlock.gif            
//SyncRequest("fengmk2PC", "Test");
InBlock.gif            
//Console.Read();
InBlock.gif
            while (true)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                Console.WriteLine(
"Enter any key except 'q' to Send message;");
InBlock.gif                Console.WriteLine(
"Enter 'q' to Exit;");
InBlock.gif                
string requestdata = "";
InBlock.gif                requestdata 
= Console.ReadLine();
InBlock.gif
InBlock.gif                
if (requestdata == "q")
InBlock.gif                    
break;
InBlock.gif                
if (requestdata.Length > 0)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    Console.WriteLine(
"Enter the HostName,");
InBlock.gif                    
string hostName = Console.ReadLine();
InBlock.gif                    Console.WriteLine(
"Enter the Message Data.");
InBlock.gif                    requestdata 
= Console.ReadLine();
InBlock.gif                    SyncRequest(hostName, requestdata);
ExpandedSubBlockEnd.gif                }

InBlock.gif                Console.WriteLine(
"");
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
public static void SyncRequest(string hostName, string requestData)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif
InBlock.gif            
//设置缓冲区
InBlock.gif
            byte[] buffer = new byte[1024];
InBlock.gif            
//向Server发出连接请求
InBlock.gif
            try
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                IPHostEntry serverHost 
= Dns.GetHostEntry(hostName);
InBlock.gif                IPEndPoint remoteEP 
= new IPEndPoint(serverHost.AddressList[0], 11010);
InBlock.gif                
//初始化ClientSocket
InBlock.gif
                Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
InBlock.gif                
//发出请求连接
InBlock.gif
                try
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    Console.WriteLine(
"ClientSocket connecting to [{0}:{1}]", serverHost.HostName, remoteEP.ToString());
InBlock.gif                    clientSocket.Connect(remoteEP);
InBlock.gif                    
//连接成功
InBlock.gif
                    Console.WriteLine("Connect Success!");
InBlock.gif                    
byte[] msg = Encoding.ASCII.GetBytes(requestData);
InBlock.gif                    
//发送请求数据
InBlock.gif
                    clientSocket.Send(msg, msg.Length, SocketFlags.None);
InBlock.gif                    Console.WriteLine(
"Send data: \r\n{0}", requestData);
InBlock.gif
InBlock.gif                    
//接收返回的响应数据
InBlock.gif
                    string receiveData = "";
InBlock.gif                    
int dataTotalSize = 0;
InBlock.gif                    
int dataSize = clientSocket.Receive(buffer, buffer.Length, SocketFlags.None);
InBlock.gif                    receiveData 
+= Encoding.ASCII.GetString(buffer, 0, dataSize);
InBlock.gif                    dataTotalSize 
+= dataSize;
InBlock.gif
InBlock.gif                    
while (dataSize > 0 && clientSocket.Available > 0)
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
dot.gif{
InBlock.gif                        dataSize 
= clientSocket.Receive(buffer, buffer.Length, SocketFlags.None);
InBlock.gif                        receiveData 
+= Encoding.ASCII.GetString(buffer, 0, dataSize);
InBlock.gif                        dataTotalSize 
+= dataSize;
ExpandedSubBlockEnd.gif                    }

InBlock.gif
InBlock.gif                    
//显示接收到的数据
InBlock.gif
                    Console.WriteLine("Received data [size:{1} bytes] from [{2}]: \r\n {0}", receiveData, dataTotalSize, clientSocket.RemoteEndPoint.ToString());
InBlock.gif                    
//释放ClientSocket
InBlock.gif
                    clientSocket.Shutdown(SocketShutdown.Both);
InBlock.gif                    clientSocket.Close();
ExpandedSubBlockEnd.gif                }

InBlock.gif                
catch (Exception e)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    Console.WriteLine(e.Message);
ExpandedSubBlockEnd.gif                }

ExpandedSubBlockEnd.gif            }

InBlock.gif            
catch (Exception e)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                Console.WriteLine(e.Message);
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

None.gif

测试如下:


(3)基于C/S架构的异步Socket示例
异步方式对应有:BeginAccept、EndAccept,BeginReceive、EndReceive,BeginSend、EndSend等方法。
异步方式:发送方发送一个数据包后,一直等到接收方响应后,才接着发送下一个数据包。

1)异步服务器端AsyncServer,异步Socket可在监听同时进行其他操作,如发送数据和读取数据。对于网络操作负荷比较大的程序来说特别适合。
对于异步ServerSocket,需要一个方法开始接受网络连接请求,一个回调方法AcceptCallback处理连接请求,一个回调方法ReceiveCallback处理接收数据,一个回调方法SendCallback处理发送数据。
ContractedBlock.gif ExpandedBlockStart.gif AsyncServerDemo
None.gifusing System;
None.gif
using System.Collections.Generic;
None.gif
using System.Text;
None.gif
using System.Net;
None.gif
using System.Net.Sockets;
None.gif
using System.Threading;
None.gif
None.gif
namespace AsyncServerDemo
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif    
class AsyncServer
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
static void Main(string[] args)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            Listening();
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
//异步读取数据的辅助类
InBlock.gif
        public class StateInfo
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
public Socket socket = null;
InBlock.gif            
public const int bufferSize = 1024;
InBlock.gif            
public byte[] buffer = new byte[bufferSize];
InBlock.gif            
public StringBuilder sb = new StringBuilder();
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
public static ManualResetEvent EventManager = new ManualResetEvent(false);
InBlock.gif
InBlock.gif        
public static void Listening()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
//获得本地地址信息
InBlock.gif
            IPHostEntry serverHost = Dns.GetHostEntry(Dns.GetHostName());
InBlock.gif            IPEndPoint serverEP 
= new IPEndPoint(serverHost.AddressList[0], 11010);
InBlock.gif            Console.WriteLine(
"Servar IP and Port is : {0}", serverEP.ToString());
InBlock.gif            
//创建ServerSocket
InBlock.gif
            Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
InBlock.gif
InBlock.gif            
try
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                serverSocket.Bind(serverEP);
InBlock.gif                serverSocket.Listen(
50);
InBlock.gif                
while (true)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    EventManager.Reset();
InBlock.gif                    
//异步监听
InBlock.gif
                    Console.WriteLine("Waiting for a connectiondot.gif");
InBlock.gif                    serverSocket.BeginAccept(
new AsyncCallback(AcceptCallback), serverSocket);
InBlock.gif                    
//监听线程将阻塞,直到有连接请求到来
InBlock.gif
                    EventManager.WaitOne();
ExpandedSubBlockEnd.gif                }

ExpandedSubBlockEnd.gif            }

InBlock.gif            
catch (Exception e)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                Console.WriteLine(e.Message);
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
public static void AcceptCallback(IAsyncResult ar)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
//唤醒监听线程
InBlock.gif
            EventManager.Set();
InBlock.gif            
//获得ClientSocke
InBlock.gif
            Socket serverSocket = (Socket)ar.AsyncState;
InBlock.gif            Socket handler 
= serverSocket.EndAccept(ar);
InBlock.gif            
//创建状态辅助对象
InBlock.gif
            StateInfo state = new StateInfo();
InBlock.gif            state.socket 
= handler;
InBlock.gif            
//读取请求数据
InBlock.gif
            handler.BeginReceive(state.buffer, 0, state.buffer.Length, SocketFlags.None,
InBlock.gif                
new AsyncCallback(ReceiveCallback), state);
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
public static void ReceiveCallback(IAsyncResult ar)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            StateInfo state 
= (StateInfo)ar.AsyncState;
InBlock.gif            
//读取数据
InBlock.gif
            int dataSize = state.socket.EndReceive(ar);
InBlock.gif            
if (dataSize > 0)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                state.sb.Append(Encoding.ASCII.GetString(state.buffer, 
0, dataSize));
InBlock.gif                
if (state.socket.Available > 0)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    state.socket.BeginReceive(state.buffer, 
0, state.buffer.Length, SocketFlags.None,
InBlock.gif                    
new AsyncCallback(ReceiveCallback), state);
ExpandedSubBlockEnd.gif                }

InBlock.gif                
else
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif//全部数据都接收完,则返回响应数据给Client
InBlock.gif                    
//显示接收数据
InBlock.gif
                    string content = state.sb.ToString();
InBlock.gif                    Console.WriteLine(
"Receive data [{0} bytes] from [{1}] at {3}:\r\n{2}",
InBlock.gif                        content.Length, state.socket.RemoteEndPoint.ToString(), content, DateTime.Now.ToLongTimeString());
InBlock.gif                    
//返回响应数据给Client
InBlock.gif
                    byte[] data = Encoding.ASCII.GetBytes(content + "\r\n Server have receive your data at " + DateTime.Now.ToLongTimeString());
InBlock.gif                    state.socket.BeginSend(data, 
0, data.Length, SocketFlags.None,
InBlock.gif                        
new AsyncCallback(SendCallback), state.socket);
ExpandedSubBlockEnd.gif                }

ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
public static void SendCallback(IAsyncResult ar)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
try
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                Socket handler 
= (Socket)ar.AsyncState;
InBlock.gif                
int sendSize = handler.EndSend(ar);
InBlock.gif                Console.WriteLine(
"Sent data [{0} bytes] to [{1}]", sendSize, handler.RemoteEndPoint.ToString());
InBlock.gif                handler.Shutdown(SocketShutdown.Both);
InBlock.gif                handler.Close();
ExpandedSubBlockEnd.gif            }

InBlock.gif            
catch (Exception e)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                Console.WriteLine(e.Message);
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

None.gif

使用之前编写的同步客户端SyncClient访问上面的异步服务器端AsyncServer,测试如下:


2)异步客户端AsyncClient
ContractedBlock.gif ExpandedBlockStart.gif AsyncClientDemo
None.gifusing System;
None.gif
using System.Collections.Generic;
None.gif
using System.Text;
None.gif
using System.Net;
None.gif
using System.Net.Sockets;
None.gif
using System.Threading;
None.gif
None.gif
namespace AsyncClientDemo
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif    
class AsyncClient
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
static void Main(string[] args)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            AsyncRequest(
"fengmk2PC""Test");
InBlock.gif            Console.Read();
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
//异步读取数据的辅助类
InBlock.gif
        public class StateInfo
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
public Socket socket = null;
InBlock.gif            
public const int bufferSize = 256;
InBlock.gif            
public byte[] buffer = new byte[bufferSize];
InBlock.gif            
public StringBuilder sb = new StringBuilder();
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
private static ManualResetEvent connectDone = new ManualResetEvent(false);
InBlock.gif        
private static ManualResetEvent sendDone = new ManualResetEvent(false);
InBlock.gif        
private static ManualResetEvent receiveDone = new ManualResetEvent(false);
InBlock.gif
InBlock.gif
InBlock.gif        
public static void AsyncRequest(string hostName, string requestData)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
try
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif
InBlock.gif                IPHostEntry serverHost 
= Dns.GetHostEntry(hostName);
InBlock.gif                IPEndPoint remoteEP 
= new IPEndPoint(serverHost.AddressList[0], 11010);
InBlock.gif                
//初始化ClientSocket
InBlock.gif
                Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
InBlock.gif                
//发出请求连接
InBlock.gif
                clientSocket.BeginConnect(remoteEP, new AsyncCallback(ConnectCallback), clientSocket);
InBlock.gif                connectDone.WaitOne();
InBlock.gif                
//发送数据到服务器端
InBlock.gif
                Send(clientSocket, requestData);
InBlock.gif                sendDone.WaitOne();
InBlock.gif                
//接收信息
InBlock.gif
                Receive(clientSocket);
InBlock.gif                receiveDone.WaitOne();
InBlock.gif                clientSocket.Shutdown(SocketShutdown.Both);
InBlock.gif                clientSocket.Close();
InBlock.gif
ExpandedSubBlockEnd.gif            }

InBlock.gif            
catch (Exception e)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                Console.WriteLine(e.Message);
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
private static void ConnectCallback(IAsyncResult ar)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
try
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                Socket handler 
= (Socket)ar.AsyncState;
InBlock.gif                handler.EndConnect(ar);
InBlock.gif                Console.WriteLine(
"Connected to {0}", handler.RemoteEndPoint.ToString());
InBlock.gif                
//连接成功
InBlock.gif
                connectDone.Set();
InBlock.gif
ExpandedSubBlockEnd.gif            }

InBlock.gif            
catch (Exception e)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                Console.WriteLine(e.Message);
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
private static void Send(Socket socket, string data)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
byte[] bytesData = Encoding.ASCII.GetBytes(data);
InBlock.gif            socket.BeginSend(bytesData, 
0, bytesData.Length, SocketFlags.None,
InBlock.gif                
new AsyncCallback(SendCallback), socket);
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
private static void SendCallback(IAsyncResult ar)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
try
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                Socket handler 
= (Socket)ar.AsyncState;
InBlock.gif                
int sendSize = handler.EndSend(ar);
InBlock.gif                Console.WriteLine(
"Sent data [{0} bytes] to [{1}]", sendSize, handler.RemoteEndPoint.ToString());
InBlock.gif                
//已发送完毕
InBlock.gif
                sendDone.Set();
InBlock.gif
ExpandedSubBlockEnd.gif            }

InBlock.gif            
catch (Exception e)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                Console.WriteLine(e.Message);
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
private static void Receive(Socket socket)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
try
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                StateInfo state 
= new StateInfo();
InBlock.gif                state.socket 
= socket;
InBlock.gif                socket.BeginReceive(state.buffer, 
0, state.buffer.Length, SocketFlags.None,
InBlock.gif                    
new AsyncCallback(ReceiveCallback), state);
InBlock.gif
ExpandedSubBlockEnd.gif            }

InBlock.gif            
catch (Exception e)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                Console.WriteLine(e.Message);
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
private static void ReceiveCallback(IAsyncResult ar)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
try
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                StateInfo state 
= (StateInfo)ar.AsyncState;
InBlock.gif                
//读取数据
InBlock.gif
                int dataSize = state.socket.EndReceive(ar);
InBlock.gif                
if (dataSize > 0)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    state.sb.Append(Encoding.ASCII.GetString(state.buffer, 
0, dataSize));
InBlock.gif                    
if (state.socket.Available > 0)
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
dot.gif{
InBlock.gif                        state.socket.BeginReceive(state.buffer, 
0, state.buffer.Length, SocketFlags.None,
InBlock.gif                        
new AsyncCallback(ReceiveCallback), state);
ExpandedSubBlockEnd.gif                    }

InBlock.gif                    
else
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
dot.gif
InBlock.gif                        
//显示接收数据
InBlock.gif
                        string content = state.sb.ToString();
InBlock.gif                        Console.WriteLine(
"Receive data [{0} bytes] from [{1}] at {3}:\r\n{2}",
InBlock.gif                            content.Length, state.socket.RemoteEndPoint.ToString(), content, DateTime.Now.ToLongTimeString());
InBlock.gif                        
//接收完毕
InBlock.gif
                        receiveDone.Set();
ExpandedSubBlockEnd.gif                    }

ExpandedSubBlockEnd.gif                }

InBlock.gif
ExpandedSubBlockEnd.gif            }

InBlock.gif            
catch (Exception e)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                Console.WriteLine(e.Message);
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

None.gif

测试如下:



(4)总结:
只要明白Socket的工作原理,即三步骤,就可以轻松地利用Socket编写网络程序。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值