当前位置:编程学堂 > C#利用服务器来实现客户端之间的通信

C#利用服务器来实现客户端之间的通信

  • 发布:2023-09-30 01:34

首先给大家说一下我自己对整个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[]数组的大小而不是内容的大小。

让我们自己尝试一下。

相关文章

最新资讯