这两天在学习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 else 104 { 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 else 112 { 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 try 24 { 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 try 41 { 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[]数组的大小而不是内容的大小。
这个大家就自己尝试吧