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