<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    靈魂-放水

    為學(xué)日益,為道日損。

    BlogJava 首頁 新隨筆 聯(lián)系 聚合 管理
      296 Posts :: 10 Stories :: 274 Comments :: 0 Trackbacks

    ??????C#網(wǎng)絡(luò)編程我們知道C#和C++的差異之一,就是他本身沒有類庫,所使用的類庫是.Net框架中的類庫--.Net FrameWork SDK。在.Net FrameWork SDK中為網(wǎng)絡(luò)編程提供了二個(gè)名稱空間:"System.Net"和"System.Net.Sockets"。C#就是通過這二個(gè)名稱空間中封裝的類和方法實(shí)現(xiàn)網(wǎng)絡(luò)通訊的。

      首先我們解釋一下在網(wǎng)絡(luò)編程時(shí)候,經(jīng)常遇到的幾個(gè)概念:同步(synchronous)、異步(asynchronous)、阻塞(Block)和非阻塞(Unblock):

      所謂同步方式,就是發(fā)送方發(fā)送數(shù)據(jù)包以后,不等接受方響應(yīng),就接著發(fā)送下一個(gè)數(shù)據(jù)包。異步方式就是當(dāng)發(fā)送方發(fā)送一個(gè)數(shù)據(jù)包以后,一直等到接受方響應(yīng)后,才接著發(fā)送下一個(gè)數(shù)據(jù)包。而阻塞套接字是指執(zhí)行此套接字的網(wǎng)絡(luò)調(diào)用時(shí),直到調(diào)用成功才返回,否則此套節(jié)字就一直阻塞在網(wǎng)絡(luò)調(diào)用上,比如調(diào)用StreamReader 類的Readlin ( )方法讀取網(wǎng)絡(luò)緩沖區(qū)中的數(shù)據(jù),如果調(diào)用的時(shí)候沒有數(shù)據(jù)到達(dá),那么此Readlin ( )方法將一直掛在調(diào)用上,直到讀到一些數(shù)據(jù),此函數(shù)調(diào)用才返回;而非阻塞套接字是指在執(zhí)行此套接字的網(wǎng)絡(luò)調(diào)用時(shí),不管是否執(zhí)行成功,都立即返回。同樣調(diào)用StreamReader 類的Readlin ( )方法讀取網(wǎng)絡(luò)緩沖區(qū)中數(shù)據(jù),不管是否讀到數(shù)據(jù)都立即返回,而不會(huì)一直掛在此函數(shù)調(diào)用上。在Windows網(wǎng)絡(luò)通信軟件開發(fā)中,最為常用的方法就是異步非阻塞套接字。平常所說的C/S(客戶端/服務(wù)器)結(jié)構(gòu)的軟件采用的方式就是異步非阻塞模式的。

      其實(shí)在用C#進(jìn)行網(wǎng)絡(luò)編程中,我們并不需要了解什么同步、異步、阻塞和非阻塞的原理和工作機(jī)制,因?yàn)樵?Net FrameWrok SDK中已經(jīng)已經(jīng)把這些機(jī)制給封裝好了。下面我們就用C#開一個(gè)具體的網(wǎng)絡(luò)程序來說明一下問題。

    一.本文中介紹的程序設(shè)計(jì)及運(yùn)行環(huán)境

        (1).微軟視窗2000 服務(wù)器版

        (2)..Net Framework SDK Beta 2以上版本

    二.服務(wù)器端程序設(shè)計(jì)的關(guān)鍵步驟以及解決辦法:

       在下面接受的程序中,我們采用的是異步阻塞的方式。

       (1).首先要要在給定的端口上面創(chuàng)建一個(gè)"tcpListener"對(duì)象偵聽網(wǎng)絡(luò)上面的請(qǐng)求。當(dāng)接收到連結(jié)請(qǐng)求后通過調(diào)用"tcpListener"對(duì)象的"AcceptSocket"方法產(chǎn)生一個(gè)用于處理接入連接請(qǐng)求的Socket的實(shí)例。下面是具體實(shí)現(xiàn)代碼:

    //創(chuàng)建一個(gè)tcpListener對(duì)象,此對(duì)象主要是對(duì)給定端口進(jìn)行偵聽
    tcpListener = new TcpListener ( 1234 ) ;
    //開始偵聽
    tcpListener.Start ( ) ;
    //返回可以用以處理連接的Socket實(shí)例
    socketForClient = tcpListener.AcceptSocket ( ) ;
       (2).接受和發(fā)送客戶端數(shù)據(jù):

       此時(shí)Socket實(shí)例已經(jīng)產(chǎn)生,如果網(wǎng)絡(luò)上有請(qǐng)求,在請(qǐng)求通過以后,Socket實(shí)例構(gòu)造一個(gè)"NetworkStream"對(duì)象,"NetworkStream"對(duì)象為網(wǎng)絡(luò)訪問提供了基礎(chǔ)數(shù)據(jù)流。我們通過名稱空間"System.IO"中封裝的二個(gè)類"StreamReader"和"StreamWriter"來實(shí)現(xiàn)對(duì)"NetworkStream"對(duì)象的訪問。其中"StreamReader"類中的ReadLine ( )方法就是從"NetworkStream"對(duì)象中讀取一行字符;"StreamWriter"類中的WriteLine ( )方法就是對(duì)"NetworkStream"對(duì)象中寫入一行字符串。從而實(shí)現(xiàn)在網(wǎng)絡(luò)上面?zhèn)鬏斪址旅媸蔷唧w的實(shí)現(xiàn)代碼:

    try
    {
    //如果返回值是"true",則產(chǎn)生的套節(jié)字已經(jīng)接受來自遠(yuǎn)方的連接請(qǐng)求
    if ( socketForClient.Connected )
    {
    ListBox1.Items.Add ( "已經(jīng)和客戶端成功連接!" ) ;
    while ( true )
    {
    //創(chuàng)建networkStream對(duì)象通過網(wǎng)絡(luò)套節(jié)字來接受和發(fā)送數(shù)據(jù)
    networkStream = new NetworkStream ( socketForClient ) ;
    //從當(dāng)前數(shù)據(jù)流中讀取一行字符,返回值是字符串
    streamReader = new StreamReader ( networkStream ) ;
    string msg = streamReader.ReadLine ( ) ;
    ListBox1.Items.Add ( "收到客戶端信息:" + msg ) ;
    streamWriter = new StreamWriter ( networkStream ) ;
    if ( textBox1.Text != "" )
    {
    ListBox1.Items.Add ( "往客戶端反饋信息:" + textBox1.Text ) ;
    //往當(dāng)前的數(shù)據(jù)流中寫入一行字符串
    streamWriter.WriteLine ( textBox1.Text ) ;
    //刷新當(dāng)前數(shù)據(jù)流中的數(shù)據(jù)
    streamWriter.Flush ( ) ;
    }
    }
    }
    }
    catch ( Exception ey )
    {
    MessageBox.Show ( ey.ToString ( ) ) ;
    }

       (3).最后別忘了要關(guān)閉所以流,停止偵聽網(wǎng)絡(luò),關(guān)閉套節(jié)字,具體如下:

    //關(guān)閉線程和流
    networkStream.Close ( ) ;
    streamReader.Close ( ) ;
    streamWriter.Close ( ) ;
    _thread1.Abort ( ) ;
    tcpListener.Stop ( ) ;
    socketForClient.Shutdown ( SocketShutdown.Both ) ;
    socketForClient.Close ( ) ;
    三.C#網(wǎng)絡(luò)編程服務(wù)器端程序的部分源代碼(server.cs) :

       由于在此次程序中我們采用的結(jié)構(gòu)是異步阻塞方式,所以在實(shí)際的程序中,為了不影響服務(wù)器端程序的運(yùn)行速度,我們?cè)诔绦蛑性O(shè)計(jì)了一個(gè)線程,使得對(duì)網(wǎng)絡(luò)請(qǐng)求偵聽,接受和發(fā)送數(shù)據(jù)都在線程中處理,請(qǐng)?jiān)谙旅娴拇a中注意這一點(diǎn),下面是server.cs的完整代碼:

    using System ;
    using System.Drawing ;
    using System.Collections ;
    using System.ComponentModel ;
    using System.Windows.Forms ;
    using System.Data ;

    using System.Net.Sockets ;
    using System.IO ;
    using System.Threading ;
    using System.Net ;
    //導(dǎo)入程序中使用到的名字空間
    public class Form1 : Form
    {
    private ListBox ListBox1 ;
    private Button button2 ;
    private Label label1 ;
    private TextBox textBox1 ;
    private Button button1 ;
    private Socket socketForClient ;
    private NetworkStream networkStream ;
    private TcpListener tcpListener ;
    private StreamWriter streamWriter ;
    private StreamReader streamReader ;
    private Thread _thread1 ;
    private System.ComponentModel.Container components = null ;
    public Form1 ( )
    {
    InitializeComponent ( ) ;
    }
    //清除程序中使用的各種資源
    protected override void Dispose ( bool disposing )
    {
    if ( disposing )
    {
    if ( components != null )
    {
    components.Dispose ( ) ;
    }
    }
    base.Dispose ( disposing ) ;
    }
    private void InitializeComponent ( )
    {
    label1 = new Label ( ) ;
    button2 = new Button ( ) ;
    button1 = new Button ( ) ;
    ListBox1 = new ListBox ( ) ;
    textBox1 = new TextBox ( ) ;
    SuspendLayout ( ) ;
    label1.Location = new Point ( 8 , 168 ) ;
    label1.Name = "label1" ;
    label1.Size = new Size ( 120 , 23 ) ;
    label1.TabIndex = 3 ;
    label1.Text = "往客戶端反饋信息:" ;
    //同樣的方式設(shè)置其他控件,這里略去

    this.Controls.Add ( button1 ) ;
    this.Controls.Add ( textBox1 ) ;
    this.Controls.Add ( label1 ) ;
    this.Controls.Add ( button2 ) ;
    this.Controls.Add ( ListBox1 ) ;
    this.MaximizeBox = false ;
    this.MinimizeBox = false ;
    this.Name = "Form1" ;
    this.Text = "C#的網(wǎng)絡(luò)編程服務(wù)器端!" ;
    this.Closed += new System.EventHandler ( this.Form1_Closed ) ;
    this.ResumeLayout ( false ) ;

    }
    private void Listen ( )
    {
    //創(chuàng)建一個(gè)tcpListener對(duì)象,此對(duì)象主要是對(duì)給定端口進(jìn)行偵聽
    tcpListener = new TcpListener ( 1234 ) ;
    //開始偵聽
    tcpListener.Start ( ) ;
    //返回可以用以處理連接的Socket實(shí)例
    socketForClient = tcpListener.AcceptSocket ( ) ;
    try
    {
    //如果返回值是"true",則產(chǎn)生的套節(jié)字已經(jīng)接受來自遠(yuǎn)方的連接請(qǐng)求
    if ( socketForClient.Connected )
    {
    ListBox1.Items.Add ( "已經(jīng)和客戶端成功連接!" ) ;
    while ( true )
    {
    //創(chuàng)建networkStream對(duì)象通過網(wǎng)絡(luò)套節(jié)字來接受和發(fā)送數(shù)據(jù)
    networkStream = new NetworkStream ( socketForClient ) ;
    //從當(dāng)前數(shù)據(jù)流中讀取一行字符,返回值是字符串
    streamReader = new StreamReader ( networkStream ) ;
    string msg = streamReader.ReadLine ( ) ;
    ListBox1.Items.Add ( "收到客戶端信息:" + msg ) ;
    streamWriter = new StreamWriter ( networkStream ) ;
    if ( textBox1.Text != "" )
    {
    ListBox1.Items.Add ( "往客戶端反饋信息:" + textBox1.Text ) ;
    //往當(dāng)前的數(shù)據(jù)流中寫入一行字符串
    streamWriter.WriteLine ( textBox1.Text ) ;
    //刷新當(dāng)前數(shù)據(jù)流中的數(shù)據(jù)
    streamWriter.Flush ( ) ;
    }
    }
    }
    }
    catch ( Exception ey )
    {
    MessageBox.Show ( ey.ToString ( ) ) ;
    }
    }
    static void Main ( )
    {
    Application.Run ( new Form1 ( ) ) ;

    }

    private void button1_Click ( object sender , System.EventArgs e )
    {
    ListBox1.Items .Add ( "服務(wù)已經(jīng)啟動(dòng)!" ) ;
    _thread1 = new Thread ( new ThreadStart ( Listen ) ) ;
    _thread1.Start ( ) ;

    }

    private void button2_Click ( object sender , System.EventArgs e )
    {
    //關(guān)閉線程和流
    networkStream.Close ( ) ;
    streamReader.Close ( ) ;
    streamWriter.Close ( ) ;
    _thread1.Abort ( ) ;
    tcpListener.Stop ( ) ;
    socketForClient.Shutdown ( SocketShutdown.Both ) ;
    socketForClient.Close ( ) ;
    }
    private void Form1_Closed ( object sender , System.EventArgs e )
    {
    //關(guān)閉線程和流
    networkStream.Close ( ) ;
    streamReader.Close ( ) ;
    streamWriter.Close ( ) ;
    _thread1.Abort ( ) ;
    tcpListener.Stop ( ) ;
    socketForClient.Shutdown ( SocketShutdown.Both ) ;
    socketForClient.Close ( ) ;
    }
    }



    Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=622873

    posted on 2006-09-24 11:17 放水老倌 閱讀(337) 評(píng)論(0)  編輯  收藏 所屬分類: 網(wǎng)絡(luò)編程
    主站蜘蛛池模板: 中文字幕永久免费视频| 国产成人免费高清激情视频| 亚洲成色WWW久久网站| 亚洲精品视频在线免费| 亚洲a∨无码一区二区| 亚洲无码在线播放| 免费在线观看的网站| 一个人看的www在线免费视频| 久久久久亚洲av无码专区| 日韩视频在线免费观看| 国产精品偷伦视频观看免费| 亚洲午夜精品久久久久久app| 国产亚洲精品激情都市| 欧美男同gv免费网站观看| 久久99久久成人免费播放| 91丁香亚洲综合社区| 亚洲中文字幕无码中文字在线 | 久久不见久久见免费影院| 91视频免费观看高清观看完整| 亚洲天堂2016| 亚洲国产精品无码成人片久久 | 久久精品国产亚洲av日韩| 免费人成在线观看播放国产 | 免费v片在线观看视频网站| 成人午夜免费视频| 亚洲精品无码日韩国产不卡av| 欧洲亚洲国产清在高| 日韩免费福利视频| 中文字幕无码不卡免费视频| 日韩精品无码免费专区网站| 国产精品亚洲二区在线| 国产成人亚洲合集青青草原精品 | 亚洲AV无码国产剧情| 精品无码一区二区三区亚洲桃色 | 亚洲人成77777在线播放网站| 国产成人在线观看免费网站 | 精品久久久久久亚洲综合网| 亚洲无砖砖区免费| 亚洲激情中文字幕| 久久精品九九亚洲精品天堂| 亚洲人成无码久久电影网站|