在分布式調(diào)度系統(tǒng)中,要實(shí)現(xiàn)調(diào)度服務(wù)器與多個(gè)計(jì)算節(jié)點(diǎn)服務(wù)器之間的通信,socket是一種實(shí)現(xiàn)方法,下面,就跟錯(cuò)新技術(shù)頻道小編一起去學(xué)C#利用服務(wù)器實(shí)現(xiàn)客戶端之間通信吧!
首先在服務(wù)端新建一個(gè)serverSocket,對(duì)其進(jìn)行初始化(一般包含AddressFamily:IP地址類(lèi)型,SocketType:Socket傳輸數(shù)據(jù)方式,ProtoType:傳輸協(xié)議);?
接著我們要設(shè)置server端要綁定的IP:port;然后開(kāi)始監(jiān)聽(tīng),并設(shè)置最多同時(shí)監(jiān)聽(tīng)多少個(gè)Client.
這時(shí),服務(wù)端就在等待狀態(tài),直到某一個(gè)Client連接到這個(gè)ip:port上,這時(shí)serverSocket.Accept()工作,獲得這個(gè)連接。(此時(shí)的連接是有地址信息的哦!記得保存)?
獲得連接之后,server就可以和這個(gè)Client進(jìn)行通信了,當(dāng)加入第二個(gè)Client(我們稱(chēng)其為ClientB)時(shí),Server接收到ClientB的消息,可以將這個(gè)消息轉(zhuǎn)發(fā)給前一個(gè)Client(我們稱(chēng)其為ClientA),當(dāng)受到ClientA的消息,也可以轉(zhuǎn)發(fā)給ClientB。這樣就實(shí)現(xiàn)了Clients之間的通信了。(重點(diǎn)在保存連接信息?。。?/p>
那么現(xiàn)在貼上代碼講解:
Server端代碼?
?
namespace SocketServer{ class Program { private static byte[] result = new byte[1024]; static Socket serverSocket; private static string client; private static Socket clientSocket; //我這里存了兩個(gè)Client,因?yàn)樽约弘娔X開(kāi)了兩個(gè)Client,不會(huì)有多的 //理論上應(yīng)該開(kāi)一個(gè)Socket[]來(lái)保存信息,最好用一個(gè)二元組將client的信息和連接綁定起來(lái) //這樣就可以實(shí)現(xiàn)斷開(kāi)連接后下次登陸還是可以識(shí)別是這個(gè)Client private static Socket clientSocketA=null; private static Socket clientSocketB=null; static void Main(string[] args) { Program.SetPort(8885); } private static void SetPort(int port) { IPAddress ip = IPAddress.Parse("127.0.0.1");//set ip serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//initialize serverSocket.Bind(new IPEndPoint(ip, port));//bind serverSocket.Listen(10); //進(jìn)入監(jiān)聽(tīng)狀態(tài) Console.WriteLine("監(jiān)聽(tīng){0}成功", serverSocket.LocalEndPoint.ToString()); //開(kāi)啟一個(gè)線程來(lái)監(jiān)聽(tīng)客戶端連接 Thread myThread = new Thread(ListenClientConnect); myThread.Start(); Console.ReadLine(); } /// <summary> /// 監(jiān)聽(tīng)客戶端連接 /// </summary> private static void ListenClientConnect() { while (true) { //Client連接上后 得到這個(gè)連接 clientSocket = serverSocket.Accept(); //這里我因?yàn)橹挥袃蓚€(gè)Client,所以就簡(jiǎn)單寫(xiě)了 if (clientSocketA == null) { clientSocketA = clientSocket; } else if (clientSocketB == null) { clientSocketB = clientSocket; } else { //當(dāng)其中一個(gè)斷開(kāi)了,又重新連接時(shí),需要再次保存連接 if (clientSocketB.IsBound) { clientSocketA = clientSocketB; clientSocketB = clientSocket; } else { clientSocketB = clientSocketA; clientSocketA = clientSocket; } } clientSocket.Send(Encoding.ASCII.GetBytes("say hello")); //開(kāi)個(gè)線程接收Client信息 Thread receivedThread = new Thread(ReceiveMessage); receivedThread.Start(clientSocket); } } private static void ReceiveMessage(object clientSocket) { Socket myClientSocket = (Socket) clientSocket; while (true) { try { int revceiveNumber = myClientSocket.Receive(result); //Console.WriteLine("接受客戶端{(lán)0}消息{1}", myClientSocket.RemoteEndPoint.ToString() // , Encoding.ASCII.GetString(result, 0, revceiveNumber)); Console.WriteLine(Encoding.ASCII.GetString(result, 0, revceiveNumber)); if (myClientSocket == clientSocketA) { Console.WriteLine("receive from A"); if (clientSocketB!=null&&clientSocketB.IsBound) { Console.WriteLine("a IS BOUND"); clientSocketB.Send(result, 0, revceiveNumber, SocketFlags.None); } else { myClientSocket.Send(Encoding.ASCII.GetBytes("the people is not online! Send Failed!")); Console.WriteLine("對(duì)方不在線上,發(fā)送失??!"); } } else { Console.WriteLine("receive from B"); if (clientSocketA != null && clientSocketA.IsBound) { Console.WriteLine("a IS BOUND"); clientSocketA.Send(result, 0, revceiveNumber, SocketFlags.None); } else { myClientSocket.Send(Encoding.ASCII.GetBytes("the people is not online! Send Failed!")); Console.WriteLine("對(duì)方不在線上,發(fā)送失敗!"); } } } catch(Exception ex) { Console.WriteLine(ex.Message); myClientSocket.Shutdown(SocketShutdown.Both); myClientSocket.Close(); break; } } } }}Client端代碼(因?yàn)槎疾畈欢?就只貼一個(gè)了)?
?
namespace SocketClient{ class Program { private static byte[] result = new byte[1024]; private static Socket clientSocket; private static void ListenServer() { while (true) { result = new byte[1024]; int receiveLength = clientSocket.Receive(result); Console.WriteLine("{0}", Encoding.ASCII.GetString(result, 0, receiveLength)); } } static void Main(string[] args) { IPAddress ip = IPAddress.Parse("127.0.0.1"); clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); try { clientSocket.Connect(ip, 8885); Console.WriteLine("連接成功!"); } catch (Exception e) { Console.WriteLine("連接失敗!"); return; } Thread threadRead = new Thread(ListenServer); threadRead.Start(); while(true) { try { Thread.Sleep(1000); string sendMessage = Console.ReadLine(); clientSocket.Send(Encoding.ASCII.GetBytes("Sylvia:"+sendMessage)); } catch (Exception ex) { clientSocket.Shutdown(SocketShutdown.Both); clientSocket.Close(); break; } } Console.WriteLine("發(fā)送完畢 按回車(chē)退出"); Console.ReadKey(); } }}寫(xiě)的時(shí)候要特別注意一下Send信息的時(shí)候,注意byte[]的傳輸大小,很容易變成byte[]數(shù)組的大小而不是內(nèi)容的大小。?
這個(gè)大家就自己嘗試吧。
以上就是錯(cuò)新技術(shù)頻道小編帶給大家的C#利用服務(wù)器實(shí)現(xiàn)客戶端之間通信,程序員可以收藏起來(lái),做到有備無(wú)患。
新聞熱點(diǎn)
疑難解答
圖片精選