tcp一般用于维持一个可信任的连接,比起udp更为安全可靠,在vs.net,分别有tcpclient和udpclient以及tcplistener,一般开发中基本可以满足需要,但是这个有个很大的弊端,对于维持一个时间较长的,相互交互的来说,数据处理不是很明朗,vs/net中还有一个socket类,用他来做一个客户/服务器段,同时在接发数据的时候,能相互独立,这需要一个异步通讯过程 先实现服务器段: using System; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading;
// State object for reading client data asynchronously namespace TcpServer { public class StateObject { // Client socket. public Socket workSocket = null; // Size of receive buffer. public const int BufferSize = 1024; // Receive buffer. public byte[] buffer = new byte[BufferSize]; // Received data string. public StringBuilder sb = new StringBuilder(); }
public class AsynchronousSocketListener { // Thread signal. public static ManualResetEvent allDone = new ManualResetEvent(false); private static Socket listener; private int _port=9010; public AsynchronousSocketListener() { } public void StopListening() { listener.Close(); } public int Port { set { _port=value; } } public void StartListening() { // Data buffer for incoming data. byte[] bytes = new Byte[1024];
// Establish the local endpoint for the socket. // The DNS name of the computer // running the listener is "host.contoso.com". IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName()); IPAddress ipAddress = ipHostInfo.AddressList[0]; IPEndPoint localEndPoint = new IPEndPoint(ipAddress, _port);
// Create a TCP/IP socket. listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp );
// Bind the socket to the local endpoint and listen for incoming connections. try { listener.Bind(localEndPoint); listener.Listen(100);
while (true) { // Set the event to nonsignaled state. allDone.Reset();
// Start an asynchronous socket to listen for connections. Console.WriteLine("接收连接.."); listener.BeginAccept( new AsyncCallback(AcceptCallback), listener );
// Wait until a connection is made before continuing. allDone.WaitOne(); }
Console.WriteLine("\nPress ENTER to continue..."); Console.Read();
}
private void AcceptCallback(IAsyncResult ar) { // Signal the main thread to continue. allDone.Set();
// Get the socket that handles the client request. Socket listener = (Socket) ar.AsyncState; Socket handler = listener.EndAccept(ar);
// Create the state object. StateObject state = new StateObject(); state.workSocket = handler; handler.BeginReceive( state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state); }
// Retrieve the state object and the handler socket // from the asynchronous state object. StateObject state = (StateObject) ar.AsyncState; Socket handler = state.workSocket; int bytesRead=0 ; // Read data from the client socket. if(handler.Connected ) {
if (bytesRead > 0) { // There might be more data, so store the data received so far.
// Check for end-of-file tag. If it is not there, read // more data. content = Encoding.ASCII.GetString( state.buffer,0,bytesRead); if (content.Length>0 && content.EndsWith("<EOF>") ) { // All the data has been read from the // client. Display it on the console. Console.WriteLine("从客户端收到 {0} bytes 数据. \n Data : {1}", content.Length, content ); // Echo the data back to the client. Send(handler, "-数据确认,已经收到-<EOF>"); } else { // Not all data received. Get more. handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state); } }
}
}
private void Send(Socket handler, String data) { // Convert the string data to byte data using ASCII encoding. byte[] byteData = Encoding.UTF8.GetBytes(data);
// Begin sending the data to the remote device. handler.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), handler); }
private void SendCallback(IAsyncResult ar) { try { // Retrieve the socket from the state object. Socket handler = (Socket) ar.AsyncState;
// Complete sending the data to the remote device. int bytesSent = handler.EndSend(ar); Console.WriteLine("发送 {0} bytes 到客户端.", bytesSent);
using System; using System.Collections; using System.Runtime.InteropServices; using System.Diagnostics; using System.Net.Sockets; using System.Net; using System.Text; using System.Threading; using System.Data; using System.Xml; using System.Xml.XPath; namespace Client {
#region 通讯对象 public delegate void NetEvent(object sender, NetEventArgs e); public class CSocket { #region 字段