客戶端與伺服器通訊
最近準備做一個考試系統,所以學習了一下C/S的通訊,就現在所知的來說,一般用的通訊方式有Web Service、Remoting,還有一種較新的技術WCF,
但我還沒學習到,所以暫不涉及。
開篇即將記錄的是最基本的Socket,在.Net中,微軟將Socket進行了很好的封裝,在基本的通訊中,需要在客戶端和伺服器端各有一個Socket,使使用者不
用瞭解底層的如TCP、Http或Udp協議就可以很輕鬆的使用。
下面是一個簡單的TcpClient和TcpListener的應用。
伺服器端通過非同步的操作在後臺監聽所有對5200埠的訪問,並獲取IP和訪問的資訊。因為從TcpClient獲得的資料流是NetWorkStream,所以我們需要相
應的流物件來對其進行解析並轉換為String,但由於在先前設定的快取大小為256位元組,所以當我們獲得的資料小於256時,後面將會是自動填充的一連串"/0",所以在
獲取資料後還應該將後面的"/0"替換掉,或是根據NetWorkStream的Read方法返回的長度,只擷取我們需要的位元組數,
可能有人會問,當傳輸的資料大於256時呢? 這時我們需要的是分步來讀取,每次讀取我們能快取的大小,並寫到另外的流中儲存,直到NetWorkStream的
Read方法返回的值等於0。
好了,本篇暫時到這裡為止。
下面是伺服器端的程式碼:
using System.Collections.Generic;
using System.Threading;
using System.Net.Sockets;
namespace AsyncWaitingConnect
{
delegatevoid asycnDelegate();
class Program
{
//宣告委託static asycnDelegate del;
static TcpListener listener;
staticbyte[] infoBytes =newbyte[256]; //設定快取為256
staticvoid
{
//完成時的回撥委託,並繫結StopListen方法 AsyncCallback callBack =new AsyncCallback(StopListen);
listener =new TcpListener(5200);
listener.Start();
//例項化委託 del =new asycnDelegate(beginWait);
//非同步開始監聽連線到本機的Client del.BeginInvoke(callBack, 0);
//任意輸入停止監聽 Console.WriteLine("Wait for Client./nEnter to Stop waiting");
Console.ReadLine();
listener.Stop();
Console.ReadLine();
}
staticvoid beginWait()
{
TcpClient client;
string clientIP, clientInfo;
//開始監聽while (true)
{
try
{
//截斷方法,用以等待客戶端連線 client = listener.AcceptTcpClient();
//獲取客戶端的IP clientIP = client.Client.RemoteEndPoint.ToString();
//獲取來自客戶端資訊的位元組流 NetworkStream ns = client.GetStream();
//轉換並輸出客戶資訊int no=ns.Read(infoBytes,0,256);
clientInfo = UnicodeEncoding.Unicode.GetString(infoBytes,0,no);
//輸出已連線客戶的資訊 Console.WriteLine("Connected IP is {0}, name is{1}",
clientIP,clientInfo);
}
catch (Exception e)
{
Console.WriteLine("連線停止!");
return;
}
}
}
//回撥的方法staticvoid StopListen(IAsyncResult ar)
{
del.EndInvoke(ar);
}
}
}
在客戶端中,連線至伺服器端,同時傳送客戶端資訊。
using System;using System.Collections.Generic;
using System.Text;
using System.Net.Sockets;
namespace AsycnWaitingConnectsClient
{
class Program
{
staticvoid Main(string[] args)
{
TcpClient client;
System.Net.IPAddress ip = System.Net.IPAddress.Parse("127.0.0.1");
for (int i =0; i <5; i++)
{
client =new TcpClient();
try
{
client.Connect(ip, 5200);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
byte[] Info = UnicodeEncoding.Unicode.GetBytes("MyName is "+ i.ToString());
client.Client.Send(Info);
}
Console.ReadLine();
}
}
}
PS:在這裡使用非同步操作的原因是考慮到之後將
實現的WinForm的監聽,如果使用同步監
聽,那在監聽的同時將會使整個窗體失去響
應...這是後面將會談到的,這裡略過。