1. 程式人生 > >Socket實現簡單的指定客戶端傳送資訊(C#)

Socket實現簡單的指定客戶端傳送資訊(C#)

Socket實現簡單的指定客戶端傳送資訊(效果如下圖)

 

不多說了,直接上程式碼:

server端:

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

class server
{
    //建立一個和客戶端通訊的套接字
    static Socket SocketWatch = null;
    //定義一個集合,儲存客戶端資訊
    static Dictionary<string, Socket> ClientConnectionItems = new Dictionary<string, Socket> { };
    public static string cID;
    static void Main(string[] args)
    {
        //埠號(用來監聽的)
        int port = 6000;
        IPAddress ip = IPAddress.Any;
        //將IP地址和埠號繫結到網路節點point上  
        IPEndPoint ipe = new IPEndPoint(ip, port);
        //定義一個套接字用於監聽客戶端發來的訊息,包含三個引數(IP4定址協議,流式連線,Tcp協議)  
        SocketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        //監聽繫結的網路節點  
        SocketWatch.Bind(ipe);
        //將套接字的監聽佇列長度限制為20  
        SocketWatch.Listen(20);
        //負責監聽客戶端的執行緒:建立一個監聽執行緒  
        Thread threadwatch = new Thread(WatchConnecting);
        //將窗體執行緒設定為與後臺同步,隨著主執行緒結束而結束  
        threadwatch.IsBackground = true;
        //啟動執行緒     
        threadwatch.Start();
        Console.WriteLine("開啟監聽......");
        Console.WriteLine("點選輸入任意資料回車退出程式......");
        Console.ReadKey();
        SocketWatch.Close();  
    }
    //監聽客戶端發來的請求  
    static void WatchConnecting()
    {
        Socket connection = null;
        //持續不斷監聽客戶端發來的請求     
        while (true)
        {
           // string cID;
            try
            {
                connection = SocketWatch.Accept();
            }
            catch (Exception ex)
            {
                //提示套接字監聽異常     
                Console.WriteLine(ex.Message);
                break;
            }
            byte[] idrec = new byte[1024 * 1024];
            int length = connection.Receive(idrec);
            cID = Encoding.UTF8.GetString(idrec, 0, length);
            ClientConnectionItems.Add(cID, connection);
            //顯示與客戶端連線情況
            Console.WriteLine("\r\n[客戶端\"" + cID + "\"建立連線成功! 客戶端數量:" + ClientConnectionItems.Count + "]");
            //獲取客戶端的IP和埠號  
            IPAddress clientIP = (connection.RemoteEndPoint as IPEndPoint).Address;
            int clientPort = (connection.RemoteEndPoint as IPEndPoint).Port;
            string sendmsg = "[" + "本端:" + cID + " 連線服務端成功!]";
            byte[] arrSendMsg = Encoding.UTF8.GetBytes(sendmsg);
            connection.Send(arrSendMsg);
            //建立一個通訊執行緒      
            Thread thread = new Thread(recv);
            //設定為後臺執行緒,隨著主執行緒退出而退出 
            thread.IsBackground = true;
            //啟動執行緒     
            thread.Start(connection);
        }
    }
   
    static void recv(object socketclientpara)
    {
        Socket socketServer = socketclientpara as Socket;

        while (true)
        {
            try
            {
                byte[] arrServerRecMsg = new byte[1024 * 1024];
                int length = socketServer.Receive(arrServerRecMsg);
                //將機器接受到的位元組陣列轉換為人可以讀懂的字串     
                string strSRecMsg = Encoding.UTF8.GetString(arrServerRecMsg, 0, length);
                string ccID = strSRecMsg.Substring(0, 4);
                int len = strSRecMsg.Length;
                string hc=cID+":"+strSRecMsg.Substring(4,len-4);
                Console.WriteLine( DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff") + "]\r\n" + strSRecMsg);
                //判斷是否包含這個客戶端
                bool contains = ClientConnectionItems.ContainsKey(ccID);
                if (contains)
                {
                    ClientConnectionItems[ccID].Send(Encoding.UTF8.GetBytes( hc));
                }
                else
                {
                    Console.WriteLine("輸入有誤,不予轉發\r\n");
                }
                arrServerRecMsg.DefaultIfEmpty();
            }
            catch (Exception)
            {
                string temp = ClientConnectionItems.First().Key;
                //提示套接字監聽異常  
                Console.WriteLine("\r\n[客戶端\"" + socketServer.RemoteEndPoint + "\"已經中斷連線! 客戶端數量:" + ClientConnectionItems.Count + "]");
                ClientConnectionItems.Remove(ClientConnectionItems.First().Key);
                Console.WriteLine("\r\n[客戶端\"" + temp + "\"已經中斷連線! 客戶端數量:" + ClientConnectionItems.Count + "]");
                break;
            }
        }
    }
}

client端(這裡只上傳了num3端,想建立更多客戶端改改名稱就行):

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


class client1
{
    //建立1個客戶端套接字和1個負責監聽服務端請求的執行緒  
    static Thread ThreadClient = null;
    static Socket SocketClient = null;
    static void Main(string[] args)
    {
        try
        {
            int port = 6000;
            string host = "127.0.0.1";//伺服器端ip地址
            IPAddress ip = IPAddress.Parse(host);
            IPEndPoint ipe = new IPEndPoint(ip, port);
            //定義一個套接字監聽  
            SocketClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            try
            {
                //客戶端套接字連線到網路節點上,用的是Connect  
                SocketClient.Connect(ipe);
                //本客戶端的ID
                string sendsStr = "num3";
                ClientSendMsg(sendsStr);
            }
            catch (Exception)
            {
                Console.WriteLine("連線失敗!\r\n");
                Console.ReadLine();
                return;
            }
            ThreadClient = new Thread(Recv);
            ThreadClient.IsBackground = true;
            ThreadClient.Start();
            Thread.Sleep(1000);
            Console.WriteLine("請輸入內容<按Enter鍵傳送>:\r\n");
            while(true)
            {
                string sendStr = Console.ReadLine();
                
                if (sendStr.Length <= 4)
                {
                    Console.WriteLine("輸入資訊長度小於5個字元,請重新輸入");
                }
                else if (sendStr.Substring(0,4)=="num3")
                {
                    
                    Console.WriteLine("請不要給自己傳送資訊");
                }
                else
                {
                    ClientSendMsg(sendStr);
                }
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
            Console.ReadLine();
        }
    }
    //接收服務端發來資訊的方法    
    public static void Recv()
    {
        //持續監聽服務端發來的訊息 
        while (true)
        {
            try
            {
                //定義一個1M的記憶體緩衝區,用於臨時性儲存接收到的訊息  
                byte[] arrRecvmsg = new byte[1024 * 1024];
                //將客戶端套接字接收到的資料存入記憶體緩衝區,並獲取長度  
                int length = SocketClient.Receive(arrRecvmsg);
                //將套接字獲取到的字元陣列轉換為人可以看懂的字串  
                string strRevMsg = Encoding.UTF8.GetString(arrRecvmsg, 0, length);
                Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff") + "\r\n" + strRevMsg + "\r\n");
            }
            catch (Exception ex)
            {
                Console.WriteLine("遠端伺服器已經中斷連線!" + ex.Message + "\r\n");
                break;
            }
        }
    }
    //傳送字元資訊到服務端的方法  
    public static void ClientSendMsg(string sendMsg)
    {
        //將輸入的內容字串轉換為機器可以識別的位元組陣列     
        byte[] arrClientSendMsg = Encoding.UTF8.GetBytes(sendMsg);
        //呼叫客戶端套接字傳送位元組陣列     
        SocketClient.Send(arrClientSendMsg);
    }
}

注:部分程式碼借鑑於https://blog.csdn.net/luming666/article/details/79125453,我只是做了一些改動,感謝這位博主。