C# Socket 初探

一、Server端
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Collections;

namespace KG_Socket_Server
{
    public partial class FrmServer : Form
    {
        public FrmServer()
        {
            InitializeComponent();
        }

        private IPAddress serverIP = IPAddress.Parse("127.0.0.1");//以本機作測試

        private IPEndPoint serverFullAddr;//完整終端地址

        private Socket sock;

        private System.Timers.Timer myTimer;

        private ArrayList alSock; //當建立了多個連接時用於保存連接

        private void btStart_Click(object sender, EventArgs e)
        {
            serverFullAddr = new IPEndPoint(serverIP, 1000);//取端口號1000

            //構造Socket對象,套接字類型爲“流套接字”,指定五元組中的協議元

            sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream,ProtocolType.Tcp);

            //指定五元組中的本地二元,即本地主機地址和端口號

            sock.Bind(serverFullAddr);

            //監聽是否有連接傳入,指定掛起的連接隊列的最大值爲20

            sock.Listen(20);

 

            alSock = new ArrayList();

 

            //構造定時器,時間間隙爲1秒,即每隔一秒執行一次accept()方法,以獲取連接請求隊列中//第一個掛起的連接請求

            myTimer = new System.Timers.Timer(1000);

            myTimer.Elapsed += new System.Timers.ElapsedEventHandler(myTimer_Elapsed);

            myTimer.Enabled = true;
        }

        private void myTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {

            myTimer.Enabled = false;

            //執行accept(),當掛起隊列爲空時將阻塞本線程,同時由於上一語句,定時器將停止,直//至有連接傳入

            Socket acceptSock = sock.Accept();

            //將accept()產生的Socket對象存入ArrayList

            alSock.Add(acceptSock);

            // 構造Threading.Timer對象,這將導致程序另啓線程。線程將執行回調函數,該委託限制//函數參數須爲object型。Threading.Timer構造器的第二個參數即傳入回調函數的參數;第//三個參數指定調用回調函數之前的延時,取0則立即啓動;最後一個參數指定調用回調函數//的時間間隔,取0則只執行一次。

            System.Threading.Timer ti = new System.Threading.Timer(new TimerCallback(ReceiveMsg), acceptSock, 0, 0);

            myTimer.Enabled = true;

        }

        private void ReceiveMsg(object obj)
        {

            Socket acceptSock = (Socket)obj;

            try
            {

                while (true)
                {

                    byte[] byteArray = new byte[100];

                    acceptSock.Receive(byteArray);//接收數據

                    //將字節數組轉成字符串

                    string strRec = System.Text.Encoding.UTF8.GetString(byteArray);

                    if (this.rtbReceive.InvokeRequired)
                    {

                        this.rtbReceive.Invoke(new EventHandler(this.ChangeRickTextBox), new object[] { strRec, EventArgs.Empty });

                    }

                }

            }

            catch (Exception ex)
            {

                acceptSock.Close();

                MessageBox.Show("S:Receive Message Error" + ex.Message);

            }

        }

        private void ChangeRickTextBox(object obj, EventArgs e)
        {

            string s = System.Convert.ToString(obj);

            this.rtbReceive.AppendText(s + Environment.NewLine);

        }

 

        private void btSend_Click(object sender, EventArgs e)
        {

            Socket sc = null;

            byte[] byteSend = System.Text.Encoding.UTF8.GetBytes(this.tbSend.Text.ToCharArray());

            try
            {

                //同時存在若干個客戶端連接時,在textBox1中輸入要發送的是哪個連接

                int index = int.Parse(this.textBox1.Text.Trim());

                sc = (Socket)alSock[index - 1];

                //發送數據

                sc.Send(byteSend);

            }

            catch (Exception ex)
            {

                if (sc != null)
                {

                    sc.Close();

                }

                MessageBox.Show("S:Send Message Error" + ex.Message);

            }

        }

 

        private void btClose_Click(object sender, EventArgs e)
        {

            try
            {

                Application.Exit();

            }

            catch (Exception ex)
            {

                MessageBox.Show("S:Close Socket Error" + ex.Message);

            }

        }

    }
}

二、Client端 
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.Threading;

 

namespace KG_Socket_Client
{
    public partial class FrmClient : Form
    {
        private IPAddress serverIP = IPAddress.Parse("127.0.0.1");

        private IPEndPoint serverFullAddr;

        private Socket sock;


        public FrmClient()
        {
            InitializeComponent();
        }

        private void btConnect_Click(object sender, EventArgs e)
        {

            try
            {

                serverFullAddr = new IPEndPoint(serverIP, 1000);

                sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream,ProtocolType.Tcp);

                sock.Connect(serverFullAddr);//建立與遠程主機的連接

 

                //啓動新線程用於接收數據

                Thread t = new Thread(new ThreadStart(ReceiveMsg));

                t.Name = "Receive Message";

                //一個線程或者是後臺線程或者是前臺線程。後臺線程與前臺線程類似,區別是後臺線//程不會防止進程終止。一旦屬於某一進程的所有前臺線程都終止,公共語言運行庫就//會通過對任何仍然處於活動狀態的後臺線程調用 Abort 來結束該進程。

                t.IsBackground = true;

                t.Start();

            }

            catch (Exception ex)
            {

                MessageBox.Show(ex.Message);

            }

        }

 

        private void ReceiveMsg()
        {

            try
            {

                while (true)
                {

                    byte[] byteRec = new byte[100];

                    this.sock.Receive(byteRec);

                    string strRec = System.Text.Encoding.UTF8.GetString(byteRec);

                    if (this.rtbReceive.InvokeRequired)
                    {

                        this.rtbReceive.Invoke(new EventHandler(ChangeRtb), new object[] { strRec, EventArgs.Empty });

                    }

                }

            }

            catch (Exception ex)
            {

                MessageBox.Show("Receive Message Error" + ex.Message);

            }

        }

 

        private void ChangeRtb(object obj, EventArgs e)
        {

            string s = System.Convert.ToString(obj);

            this.rtbReceive.AppendText(s + Environment.NewLine);

        }

 

        private void btSend_Click(object sender, EventArgs e)
        {

            byte[] byteSend =

System.Text.Encoding.UTF8.GetBytes(this.tbSend.Text.ToCharArray());

            try
            {

                this.sock.Send(byteSend);

            }

            catch
            {

                MessageBox.Show("Send Message Error");

            }

        }

 

        private void btClose_Click(object sender, EventArgs e)
        {

            try
            {

                this.sock.Shutdown(SocketShutdown.Receive);

                this.sock.Close();

                Application.Exit();

            }

            catch
            {

                MessageBox.Show("Exit Error");

            }

        }


    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章