c# socket 編程

轉   http://www.cnblogs.com/cailangwei/archive/2011/11/21/2258191.htmlhtml

 

基於Socket服務器端實現本例主要是創建多客戶端與服務器之間的數據傳輸,首先設計服務器。打開VS2008,在D:\C#\ch17目錄下創建名爲SocketServer的Windows應用程序。打開工程,往當前窗體中添加控件,如表17-6所示。
表17-6  添加控件列表數據庫

控    件服務器

Name網絡

Textide

ListBox函數

lbInfo測試

 

Labelthis

labelspa

 

Button線程

button1

啓動服務器

設計好的界面如圖17-2所示。


接下來開始運用前面的知識設計服務器,主要分爲如下步驟。
(1)首先是對一些命名空間的包含,包括System.Net、System.Net.Sockets、System.IO和System.Threading。而後定義一系列的全局變量,以下所示。
 

複製代碼
private Socket s;                                    //定義Socket對象
private Thread th; //客戶端鏈接服務器的線程
public Socket cSocket; //單個客戶端鏈接的Socket對象
public NetworkStream ns; //網絡流
public StreamReader sr; //流讀取
public StreamWriter sw; //流寫入
private delegate void SetTextCallback(); //用於操做主線程控件
複製代碼


(2)接下來是設計客戶端鏈接的管理,主要包括服務器與客戶端之間的鏈接和收發數據問題,把它們放在一個函數Communication裏,以下所示。

複製代碼
public void Communication()
{
while (true)
{
try
{
cSocket = s.Accept(); //用cSocket來表明該客戶端鏈接
if (cSocket.Connected) //測試是否鏈接成功
{
ns = new NetworkStream(cSocket); //創建網絡流,便於數據的讀取
sr = new StreamReader(ns); //實例化流讀取對象
sw = new StreamWriter(ns); //實例化寫入流對象
test(); //從流中讀取
sw.WriteLine("收到請求,容許鏈接"); //向流中寫入數據
sw.Flush(); //清理緩衝區
}
else
{
MessageBox.Show("鏈接失敗");
}
}
catch (SocketException ex)
{
MessageBox.Show(ex.Message); //捕獲Socket異常
}
catch (Exception es)
{
MessageBox.Show("其餘異常" + es.Message); //捕獲其餘異常
}
}
}
//如下代碼的用法在第16章有關線程的用法時曾提到過,主要用於從當前線程操做主線程中的控件,這裏就不在贅//述
public void send()
{
lbInfo.Items.Add(sr.ReadLine()+"\n");
}
public void test()
{
SetTextCallback stcb = new SetTextCallback(send);
Invoke(stcb);
}
複製代碼


 

(3)定義好與客戶端的鏈接後,接下來須要利用線程來啓動,雙擊「啓動服務器」按鈕,添加以下代碼。
 

複製代碼
 button1.Enabled = false;
s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//建立Socket對象
IPAddress serverIP = IPAddress.Parse("222.18.142.171");
IPEndPoint server = new IPEndPoint(serverIP,13); //實例化服務器的IP和端口
s.Bind(server);
s.Listen(10);
try
{
th = new Thread(new ThreadStart(Communication)); //建立線程
th.Start(); //啓動線程
label1.Text = "服務器啓動成功!";
}
catch(Exception ex)
{
MessageBox.Show("服務器啓動失敗!" + ex.Message);
}
複製代碼


(4)最後在關閉服務器窗口的時候,還應該關閉線程和當前Socket鏈接,代碼以下所示。
 

複製代碼
protected override void Dispose(bool disposing)
{
try
{
if (disposing && (components != null))
{
components.Dispose();
th.Abort();
//禁用當前Socket鏈接中的數據收發
s.Shutdown(System.Net.Sockets.SocketShutdown.Both);
s.Close();
}
base.Dispose(disposing);
}
catch
{
return;
}
}
//接着爲當前窗體的FormClosed事件添加以下代碼。
this.Close();
複製代碼


至此,服務器就設計完了,下面接着看客戶端。
基於Socket客戶端實現打開VS2008,在D:\C#\ch17目錄下創建名爲SocketClient的Windows應用程序。打開工程,往當前窗體中添加控件,如表17-7所示。
表17-7  添加控件列表

控 件 名

Name

Text

GroupBox

groupBox1

向服務器發送消息

Label

label1

發送消息:

TextBox

textBox1

 

Button

button2

發送

ListBox

lbInfo

 

GroupBox

groupBox1

服務器回饋信息


客戶端的設計主要分爲如下步驟。
(1)首先要作的工做仍是要引用一些命名空間,以下所示。

using System.IO; 
using System.Net.Sockets;
using System.Net;

  而後定義一系列的全局變量,以下所示。  

private Socket s;                                         //定義Socket對象                  
public NetworkStream ns; //網絡流
public StreamReader sr; //流讀取
public StreamWriter sw; //流寫入

(2)雙擊「發送」按鈕,添加以下代碼。

複製代碼
s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
serverIP = IPAddress.Parse("222.18.142.171"); //服務器IP
try
{
s.Connect(serverIP, 13); //鏈接服務器,端口號用13
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
try
{
ns = new NetworkStream(s); //實例化網絡流
sr = new StreamReader(ns); //實例化流讀取對象
sw = new StreamWriter(ns); //實例化寫入流對象
sw.WriteLine(textBox1.Text); //將textBox1.Text的數據寫入流
sw.Flush(); //清理緩衝區
lbInfo.Items.Add(sr.ReadLine()); //將從流中讀取的數據寫入lbInfo28 }
catch (Exception ex)
{
MessageBox.Show(ex.Message); //捕獲異常
}
複製代碼

(3)最後,關閉Socket鏈接,釋放資源,能夠直接在窗體的FormClosed事件中進行,以下所示。s.Shutdown(SocketShutdown.Both);s.Close();至此,服務器和客戶端已經所有設計完畢,下面看運行效果。基於Socket的C/S實例的運行首先,啓動服務器程序,單擊「啓動服務器」按鈕,如圖17-4所示。接着再啓動客戶端,並在textBox1輸入數據(中英文皆可),屢次單擊「發送」按鈕,如圖17-5所示。此時,服務器的狀態如圖17-6所示。收到客戶端發送的數據從圖17-6中能夠看出,此時服務器已經收到來自客戶端的數據,而圖17-5中顯示客戶端也收到了來自服務器的回饋消息。此外,本例還能實現多個客戶端向一個服務器同時收發數據,並已經在三臺計算機(一個服務器和兩個客戶端)上測試經過。本例只是實現了服務器與客戶端最簡單的數據傳輸,讀者若是有興趣能夠在此基礎上再添加其餘功能,好比能夠利用前面講的數據庫知識,在服務器端寫個用戶登陸驗證,讓客戶端經過驗證後才能收發數據等。在網絡中,收發數據會常常使用Socket。本節中主要運用了幾節中介紹的Socket基礎知識完成了一個簡單的基於流的C/S模式例子。在下一節中,將介紹另外一種傳輸方式——基於數據報(UDP)。

相關文章
相關標籤/搜索