1. 程式人生 > >客戶端與伺服器通訊

客戶端與伺服器通訊

       最近準備做一個考試系統,所以學習了一下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;
using System.Collections.Generic;
using System.Text;
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
 Main(string[] args)
        {
            
//完成時的回撥委託,並繫結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的監聽,如果使用同步監
                                                                                                  聽,那在監聽的同時將會使整個窗體失去響
                                                                                                  應...這是後面將會談到的,這裡略過。