博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C#利用服务器实现客户端之间通信
阅读量:5052 次
发布时间:2019-06-12

本文共 7699 字,大约阅读时间需要 25 分钟。

这两天在学习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         ///  36         /// 监听客户端连接 37         ///  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[]数组的大小而不是内容的大小。

这个大家就自己尝试吧

转载于:https://www.cnblogs.com/sylvialucy/p/5736862.html

你可能感兴趣的文章
枚举的使用
查看>>
BZOJ 1531 二进制优化多重背包
查看>>
BZOJ 2324 (有上下界的)费用流
查看>>
python3基础06(随机数的使用)
查看>>
Zookeeper系列(二)特征及应用场景
查看>>
【HTTP】Fiddler(三)- Fiddler命令行和HTTP断点调试
查看>>
Spring Boot使用Druid和监控配置
查看>>
poi 处理空单元格
查看>>
Android 内存泄漏优化总结
查看>>
luogu4849 寻找宝藏 (cdq分治+dp)
查看>>
Spring Cloud微服务笔记(五)Feign
查看>>
C语言键盘按键列表
查看>>
Codeforces Round #374 (Div. 2)
查看>>
oracle数据类型
查看>>
socket
查看>>
Vue中使用key的作用
查看>>
二叉索引树 树状数组
查看>>
日志框架--(一)基础篇
查看>>
Java设计模式之原型模式
查看>>
Spring学习(四)-----Spring Bean引用同xml和不同xml bean的例子
查看>>