首先给大家说一下我自己对整个Socket通信流程的理解。毕竟我是初学者,所以我对我的错误表示歉意。知道错了我会改正的~
首先在服务器端新建一个serverSocket并初始化(一般包括AddressFamily:IP地址类型、SocketType:Socket数据传输方式、ProtoType:传输协议);
然后我们需要设置与服务器绑定的IP:端口;然后开始监控,并设置同时监控的最大Client数量。
此时,服务器正在等待,直到某个Client连接到这个ip:port。此时,serverSocket.Accept()开始获取连接。 (此时的连接有地址信息!记得保存)
获得连接后,服务器端即可与客户端进行通信。当加入第二个Client(我们称之为ClientB)时,Server接收来自ClientB的消息,并可以将消息转发给前一个Client(我们称之为ClientB)。称之为ClientA),当收到ClientA的消息时,也可以转发给ClientB。这样就实现了Client之间的通信。 (重点是保存连接信息!!)
所以现在我把代码解释贴出来:
服务器端代码
命名空间 SocketServer { 班级计划 { 私有静态字节[]结果=新字节[1024]; 静态套接字服务器套接字; 私有静态字符串客户端; 私有静态Socket clientSocket; //我这里保存了两个客户端,因为我电脑上打开了两个客户端,所以不会很多。 //理论上应该打开一个Socket[]来保存信息。最好使用元组来绑定客户端的信息和连接。 //这样,断开连接后,下次登录仍然可以识别客户端。私有静态套接字 clientSocketA=null; 私有静态套接字 clientSocketB=null; 静态无效主(字符串[]参数) { 程序.SetPort(8885); } 私有静态无效SetPort(int端口) { IPAddress ip = IPAddress.Parse("127.0.0.1");//设置ip serverSocket = new Socket(AddressFamily.InterNetwork, www.sychzs.cn, ProtocolType.Tcp);//初始化 serverSocket.Bind(new IPEndPoint(ip, port));//绑定 serverSocket.Listen(10); //进入监听状态 Console.WriteLine("监听{0}成功", serverSocket.LocalEndPoint.ToString()); //启动一个线程来监听客户端连接 线程 myThread = new Thread(ListenClientConnect); myThread.Start(); Console.ReadLine(); } ////// 监听客户端连接 /// 私有静态无效 ListenClientConnect() { 而(真) { //客户端连接后获取此连接 clientSocket = serverSocket.Accept(); //这里我只是这么写,因为只有两个Client。if (clientSocketA == null) { clientSocketA = clientSocket; } 否则如果(clientSocketB == null) { clientSocketB = clientSocket; } 别的 { //当其中一个断开并重新连接时,需要再次保存连接 if (clientSocketB.IsBound) { clientSocketA = clientSocketB; clientSocketB = clientSocket; } 别的 { clientSocketB = clientSocketA; clientSocketA = clientSocket; } } clientSocket.Send(Encoding.ASCII.GetBytes("打个招呼")); //开启一个线程接收Client信息 线程 receiveThread = new Thread(ReceiveMessage); receiveThread.Start(clientSocket); } } 私有静态无效ReceiveMessage(对象clientSocket) { 套接字 myClientSocket = (Socket) clientSocket; 而(真) { 尝试 {int revceiveNumber = myClientSocket.Receive(结果); //Console.WriteLine("接受客户端{0}消息{1}", myClientSocket.RemoteEndPoint.ToString() // , Encoding.ASCII.GetString(result, 0, revceiveNumber)); Console.WriteLine(Encoding.ASCII.GetString(结果, 0, revceiveNumber)); if (myClientSocket == clientSocketA) { Console.WriteLine("从A接收"); if (clientSocketB!=null&&clientSocketB.IsBound) { Console.WriteLine("a 已绑定"); clientSocketB.Send(结果, 0, revceiveNumber, SocketFlags.None); } 别的 { myClientSocket.Send(Encoding.ASCII.GetBytes("对方不在线!发送失败!")); Console.WriteLine("对方不在线上,发送失败!"); } } 别的 { Console.WriteLine("从B接收");if (clientSocketA != null && clientSocketA.IsBound) { Console.WriteLine("a 已绑定"); clientSocketA.Send(结果, 0, revceiveNumber, SocketFlags.None); } 别的 { myClientSocket.Send(Encoding.ASCII.GetBytes("对方不在线!发送失败!")); Console.WriteLine("对方不在线,发送失败!"); } } } 捕获(异常前) { Console.WriteLine(例如.Message); myClientSocket.Shutdown(SocketShutdown.Both); myClientSocket.Close(); 休息; } } } } }
客户端代码(因为几乎一样,我只贴一个)
命名空间 SocketClient { 班级计划 { 私有静态字节[]结果=新字节[1024]; 私有静态Socket clientSocket; 私有静态无效ListenServer() { 而(真) { 结果=新字节[1024];int receiveLength = clientSocket.Receive(结果); Console.WriteLine("{0}", Encoding.ASCII.GetString(结果, 0, receiveLength)); } } 静态无效主(字符串[]参数) { IPAddress ip = IPAddress.Parse("127.0.0.1"); clientSocket = new Socket(AddressFamily.InterNetwork, www.sychzs.cn, ProtocolType.Tcp); 尝试 { clientSocket.Connect(ip, 8885); Console.WriteLine("连接成功!"); } 捕获(异常 e) { Console.WriteLine("连接失败!"); 返回; } 线程 threadRead = new Thread(ListenServer); threadRead.Start(); 而(真) { 尝试 { 线程.睡眠(1000); 字符串 sendMessage = Console.ReadLine(); clientSocket.Send(Encoding.ASCII.GetBytes("西尔维娅:"+sendMessage)); } catch(异常前) {clientSocket.Shutdown(SocketShutdown.Both); clientSocket.Close(); 休息; } } Console.WriteLine("发送完成,按回车退出"); Console.ReadKey(); } } }
写入时,要特别注意写入Send信息时byte[]的传输大小。它很容易变成byte[]数组的大小而不是内容的大小。
让我们自己尝试一下。