你的位置:首页 > ASP.net教程

[ASP.net教程]C#利用服务器实现客户端之间通信


这两天在学习C#,C#高级编程真的是厚厚的一本书QAQ。

昨天看了一下里面的通信部分(其实还没怎么看),看了网上一些人的博客,自己在他们的博客基础上写了一个通信。

先来讲述下我自己对于整个Socket通信过程的理解,毕竟初学,说错见谅,知道错了会改正~

首先在服务端新建一个serverSocket,对其进行初始化(一般包含AddressFamily:IP地址类型,SocketType:Socket传输数据方式,ProtoType:传输协议);

接着我们要设置server端要绑定的IP:port;然后开始监听,并设置最多同时监听多少个Client.

 

这时,服务端就在等待状态,直到某一个Client连接到这个ip:port上,这时serverSocket.Accept()工作,获得这个连接。(此时的连接是有地址信息的哦!记得保存)

获得连接之后,server就可以和这个Client进行通信了,当加入第二个Client(我们称其为ClientB)时,Server接收到ClientB的消息,可以将这个消息转发给前一个Client(我们称其为ClientA),当受到ClientA的消息,也可以转发给ClientB。这样就实现了Clients之间的通信了。(重点在保存连接信息!!

 

那么现在贴上代码讲解:

Server端代码

 1 namespace SocketServer 2 { 3   class Program 4   { 5     private static byte[] result = new byte[1024]; 6     7     static Socket serverSocket; 8     private static string client; 9     private static Socket clientSocket; 10     //我这里存了两个Client,因为自己电脑开了两个Client,不会有多的 11     //理论上应该开一个Socket[]来保存信息,最好用一个二元组将client的信息和连接绑定起来 12     //这样就可以实现断开连接后下次登陆还是可以识别是这个Client 13     private static Socket clientSocketA=null; 14     private static Socket clientSocketB=null; 15      16     static void Main(string[] args) 17     { 18       Program.SetPort(8885); 19     } 20     private static void SetPort(int port) 21     { 22       IPAddress ip = IPAddress.Parse("127.0.0.1");//set ip 23       serverSocket = new Socket(AddressFamily.InterNetwork, 24         SocketType.Stream, ProtocolType.Tcp);//initialize 25       serverSocket.Bind(new IPEndPoint(ip, port));//bind 26       serverSocket.Listen(10); 27       //进入监听状态 28       Console.WriteLine("监听{0}成功", serverSocket.LocalEndPoint.ToString()); 29       //开启一个线程来监听客户端连接 30       Thread myThread = new Thread(ListenClientConnect); 31       myThread.Start(); 32       Console.ReadLine(); 33  34     } 35     /// <summary> 36     /// 监听客户端连接 37     /// </summary> 38     private static void ListenClientConnect() 39     { 40       while (true) 41       { 42         //Client连接上后 得到这个连接 43         clientSocket = serverSocket.Accept(); 44  45         //这里我因为只有两个Client,所以就简单写了 46         if (clientSocketA == null) 47         { 48           clientSocketA = clientSocket; 49         } 50         else if (clientSocketB == null) 51         { 52           clientSocketB = clientSocket; 53         } 54         else 55         { 56           //当其中一个断开了,又重新连接时,需要再次保存连接 57           if (clientSocketB.IsBound) 58           { 59             clientSocketA = clientSocketB; 60             clientSocketB = clientSocket; 61           } 62           else 63           { 64             clientSocketB = clientSocketA; 65             clientSocketA = clientSocket; 66           } 67            68         } 69         clientSocket.Send(Encoding.ASCII.GetBytes("say hello")); 70         //开个线程接收Client信息 71         Thread receivedThread = new Thread(ReceiveMessage); 72         receivedThread.Start(clientSocket); 73  74       } 75     } 76    77     private static void ReceiveMessage(object clientSocket) 78     { 79       Socket myClientSocket = (Socket) clientSocket; 80        81       while (true) 82       { 83         try 84         { 85           int revceiveNumber = myClientSocket.Receive(result); 86           //Console.WriteLine("接受客户端{0}消息{1}", myClientSocket.RemoteEndPoint.ToString() 87           //  , Encoding.ASCII.GetString(result, 0, revceiveNumber)); 88           Console.WriteLine(Encoding.ASCII.GetString(result, 0, revceiveNumber)); 89           if (myClientSocket == clientSocketA) 90           { 91             Console.WriteLine("receive from A"); 92             if (clientSocketB!=null&&clientSocketB.IsBound) 93             { 94               Console.WriteLine("a IS BOUND"); 95               clientSocketB.Send(result, 0, revceiveNumber, SocketFlags.None); 96             } 97             else 98             { 99               myClientSocket.Send(Encoding.ASCII.GetBytes("the people is not online! Send Failed!"));100               Console.WriteLine("对方不在线上,发送失败!");101             }102           }103           else104           {105             Console.WriteLine("receive from B");106             if (clientSocketA != null && clientSocketA.IsBound)107             {108               Console.WriteLine("a IS BOUND");109               clientSocketA.Send(result, 0, revceiveNumber, SocketFlags.None);110             }  111             else112             {113               myClientSocket.Send(Encoding.ASCII.GetBytes("the people is not online! Send Failed!"));114               Console.WriteLine("对方不在线上,发送失败!");115             }116 117           }118           119         }120         catch(Exception ex)121         {122           Console.WriteLine(ex.Message);123           myClientSocket.Shutdown(SocketShutdown.Both);124           myClientSocket.Close();125           break;126 127         }128       }129 130     }131   }132 }

Client端代码(因为都差不多 就只贴一个了)

 1 namespace SocketClient 2 { 3   class Program 4   { 5     private static byte[] result = new byte[1024]; 6     private static Socket clientSocket; 7     private static void ListenServer() 8     { 9       while (true)10       {11         result = new byte[1024];12         int receiveLength = clientSocket.Receive(result);13         14         Console.WriteLine("{0}", Encoding.ASCII.GetString(result, 0, receiveLength));15       }16      17     }18     static void Main(string[] args)19     {20 21       IPAddress ip = IPAddress.Parse("127.0.0.1");22       clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);23       try24       {25         clientSocket.Connect(ip, 8885);26         Console.WriteLine("连接成功!");27 28       }29       catch (Exception e)30       {31         Console.WriteLine("连接失败!");32         return;33       }34       Thread threadRead = new Thread(ListenServer);35       threadRead.Start();36      37 38       while(true)39       {40         try41         {42           Thread.Sleep(1000);43           string sendMessage = Console.ReadLine();44           clientSocket.Send(Encoding.ASCII.GetBytes("Sylvia:"+sendMessage));45           46         }47         catch (Exception ex)48         {49           clientSocket.Shutdown(SocketShutdown.Both);50           clientSocket.Close();51           break;52         }53 54       }55       Console.WriteLine("发送完毕 按回车退出");56       Console.ReadKey();57     }58   }59 }

 

写的时候要特别注意一下Send信息的时候,注意byte[]的传输大小,很容易变成byte[]数组的大小而不是内容的大小。

这个大家就自己尝试吧