c#socket TCP同步網絡通信


一、socket簡介

  socket就是套接字,它是引用網絡連接的特殊文件描述符,由三個基本要素組成:

    1: AddressFamily(網絡類型)

    2: SocketType(數據傳輸類型)

    3:ProtocolType(采用的網絡協議)

  下面是可用於IP通信的套接字組合及其常用的屬性和方法

 

二、socket與網絡通信 

  IP連接領域有兩種通信類型:面向連接的和無連接的,這里我要講的是面向連接的,使用TCP協議來建立兩個IP的值端點之間的會話,下面是它的基本步驟。

    a:建立一個套接字

    b:綁定本機的IP和端口

    c:使用listen()方法監聽別人發過來的東西

    d:如果監聽到連接,則可以使用Send/Receive來執行操作

    e:完成后使用Close()方法進行關閉

  工作原理如圖所示:

  

 

三、一個簡單的同步通信示例

  下面的例子中,服務器向所有連接的客戶端發送消息,實現多播功能

using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;

namespace ServerFinally
{
    class Program
    {
        //定義兩個鏈表,分別存儲連接的客戶端和斷開的客戶端信息類
        //並不是一個socket,而是自己寫的一個輔助類
        public static List<ClientCon> connectSockets = new List<ClientCon>();   
        public static List<ClientCon> disConnectSockets = new List<ClientCon>();
        static void Main(string[] args)
        {
            //通過dns類獲取本機ip地址(也可以直接輸入IP地址)
            IPHostEntry ipHostInfo = Dns.GetHostEntry(Dns.GetHostName());
            IPAddress ipaddress = ipHostInfo.AddressList[2];
            IPEndPoint ipe = new IPEndPoint(ipaddress, 9999);

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

            try
            {
                listener.Bind(ipe);
                listener.Listen(10);

                //死循環 一直等待客戶端連接
                while (true)
                {
                    Console.WriteLine("Wait for a connnect...");
                    Socket client = listener.Accept();  //阻塞當前線程
                    Console.WriteLine("A client is connct...");

                    //每次連接一個客戶端,將其加入鏈表
                    ClientCon clientCon = new ClientCon(client);
                    connectSockets.Add(clientCon);

                    //開啟線程調用接受消息方法,一直接受消息
                    Thread t = new Thread(clientCon.ReceiveMessage);
                    t.Start();

                    Console.WriteLine("Start receive");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }

        //廣播消息,將信息發送至所有已連接的客戶端
        public static void BroadcastMessage(string data)
        {
            foreach (ClientCon client in connectSockets)
            {
                //判斷鏈表中的客戶端是否已經斷開,未斷開連接就向其發送消息,否則從中移除
                if (client.IsConnected)
                {
                    client.SendMessage(data);
                }
                else
                {
                    disConnectSockets.Add(client);
                }
            }

            foreach (ClientCon disConnect in disConnectSockets)
            {
                connectSockets.Remove(disConnect);
            }
        }
    }
}
服務端
using System;
using System.Collections.Generic;
using System.Net.Sockets;
using System.Text;

namespace ServerFinally
{
    /// <summary>
    /// 客戶端連接輔助類
    /// </summary>
    class ClientCon
    {
        Socket client;

        //判斷當前客戶端是否斷開連接
        public bool IsConnected
        {
            get;
            set;
        }

        //構造函數 調用的時候為cliet賦值
        public ClientCon(Socket s)
        {
            client = s;
            IsConnected = true;
        }

        //接受客戶端發送的信息
        public void ReceiveMessage()
        {
            byte[] buffer = new byte[1024];
            string data = "";

            while (true)
            {
                try
                {
                    //判斷客戶端是否斷開連接
                    if (!client.Poll(10, SelectMode.SelectRead))
                    {
                        int length = client.Receive(buffer);
                        data = Encoding.UTF8.GetString(buffer, 0, length);
                        if (data != "")
                        {
                            Console.WriteLine("Receive message is :" + data);
                            Program.BroadcastMessage(data);
                        }
                    }
                    else
                    {
                        IsConnected = false;
                        Console.WriteLine("A client is disconnect");
                        break;
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }
            }
        }

        //發送消息
        public void SendMessage(string data)
        {
            byte[] buffer = new byte[1024];
            buffer = Encoding.UTF8.GetBytes(data);
            client.Send(buffer);
        }
    }
}
服務器端輔助類

 

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;

namespace ClientFinally
{
    class Program
    {
        static Socket client;
        static Thread t;
        static void Main(string[] args)
        {
            //通過IP地址和端口定義一個IPEndPoint類
            IPEndPoint ipe = new IPEndPoint(IPAddress.Parse("10.128.119.68"), 9999);
            client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            try
            {
                //連接服務器
                client.Connect(ipe);
                Console.WriteLine("Connnect to {0}", client.RemoteEndPoint.ToString());

                //開啟線程 接收消息
                t = new Thread(ReceiveMessage);
                t.Start();

                //通過死循環發送消息
                while (true)
                {
                    byte[] bytes = new byte[1024];
                    Console.WriteLine("Please input you message:");
                    string mes = Console.ReadLine();

                    //如果輸入的內容為空 關閉此客戶端
                    if (mes == "")
                    {
                        client.Shutdown(SocketShutdown.Both);
                        client.Close();
                        break;
                    }
                    bytes = Encoding.UTF8.GetBytes(mes);

                    //發送消息
                    client.Send(bytes);
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
        }

        //接收消息
        private static void ReceiveMessage()
        {
            while (true)
            {
                try
                {
                    byte[] buffer = new byte[1024];
                    //length為接收信息長度
                    int length = client.Receive(buffer);
                    if (length > 0)
                    {
                        Console.WriteLine("receive message:" + Encoding.UTF8.GetString(buffer));
                    }
                }
                catch
                {
                    break;
                }
            }
        }
    }
}
客戶端代碼

 

先啟動服務器端,在啟動客戶端,效果如下

 

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM