📜  C#中的套接字编程

📅  最后修改于: 2021-05-29 15:24:12             🧑  作者: Mango

套接字编程是一种连接网络上的两个节点以相互通信的方法。基本上,这是一种单向客户端和服务器设置,其中客户端连接,将消息发送到服务器,并且服务器使用套接字连接显示消息。一个套接字(节点)在IP上的特定端口上侦听,而另一个套接字伸向另一个套接字以建立连接。当客户端与服务器联系时,服务器形成侦听器套接字。在深入研究服务器和客户端代码之前,强烈建议您使用TCP / IP模型

客户端编程

在创建客户端套接字之前,用户必须确定他要连接到的“ IP地址”,在这种情况下,它是localhost 。同时,我们还需要属于套接字本身的’Family’方法。然后,通过’ connect ‘方法,我们将套接字连接到服务器。发送任何消息之前,必须将其转换为字节数组。然后并且只有那时,它才能通过’ send ‘方法发送到服务器。后来,由于使用了“ receive ”方法,我们将获得一个字节数组作为服务器的答案。值得注意的是,就像在C语言中一样,“发送”和“接收”方法仍然返回已发送或已接收的字节数。

// A C# program for Client
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
  
namespace Client {
  
class Program {
  
// Main Method
static void Main(string[] args)
{
    ExecuteClient();
}
  
// ExecuteClient() Method
static void ExecuteClient()
{
  
    try {
          
        // Establish the remote endpoint 
        // for the socket. This example 
        // uses port 11111 on the local 
        // computer.
        IPHostEntry ipHost = Dns.GetHostEntry(Dns.GetHostName());
        IPAddress ipAddr = ipHost.AddressList[0];
        IPEndPoint localEndPoint = new IPEndPoint(ipAddr, 11111);
  
        // Creation TCP/IP Socket using 
        // Socket Class Costructor
        Socket sender = new Socket(ipAddr.AddressFamily,
                   SocketType.Stream, ProtocolType.Tcp);
  
        try {
              
            // Connect Socket to the remote 
            // endpoint using method Connect()
            sender.Connect(localEndPoint);
  
            // We print EndPoint information 
            // that we are connected
            Console.WriteLine("Socket connected to -> {0} ",
                          sender.RemoteEndPoint.ToString());
  
            // Creation of messagge that
            // we will send to Server
            byte[] messageSent = Encoding.ASCII.GetBytes("Test Client");
            int byteSent = sender.Send(messageSent);
  
            // Data buffer
            byte[] messageReceived = new byte[1024];
  
            // We receive the messagge using 
            // the method Receive(). This 
            // method returns number of bytes
            // received, that we'll use to 
            // convert them to string
            int byteRecv = sender.Receive(messageReceived);
            Console.WriteLine("Message from Server -> {0}", 
                  Encoding.ASCII.GetString(messageReceived, 
                                             0, byteRecv));
  
            // Close Socket using 
            // the method Close()
            sender.Shutdown(SocketShutdown.Both);
            sender.Close();
        }
          
        // Manage of Socket's Exceptions
        catch (ArgumentNullException ane) {
              
            Console.WriteLine("ArgumentNullException : {0}", ane.ToString());
        }
          
        catch (SocketException se) {
              
            Console.WriteLine("SocketException : {0}", se.ToString());
        }
          
        catch (Exception e) {
            Console.WriteLine("Unexpected exception : {0}", e.ToString());
        }
    }
      
    catch (Exception e) {
          
        Console.WriteLine(e.ToString());
    }
}
}
}
服务器端编程

同样,我们需要一个“ IP地址”来标识服务器,以允许客户端进行连接。创建套接字后,我们调用’ bind ‘方法,该方法将IP绑定到套接字。然后,调用“监听”方法。该操作负责创建与每个打开的“套接字”相关的等待队列。 “监听”方法将可以保留在等待队列中的最大客户端数作为输入。如上所述,通过“发送”和“接收”方法与客户端进行通信。

注意:不要忘记转换为字节数组。

// A C# Program for Server
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
  
namespace Server {
  
class Program {
  
// Main Method
static void Main(string[] args)
{
    ExecuteServer();
}
  
public static void ExecuteServer()
{
    // Establish the local endpoint 
    // for the socket. Dns.GetHostName
    // returns the name of the host 
    // running the application.
    IPHostEntry ipHost = Dns.GetHostEntry(Dns.GetHostName());
    IPAddress ipAddr = ipHost.AddressList[0];
    IPEndPoint localEndPoint = new IPEndPoint(ipAddr, 11111);
  
    // Creation TCP/IP Socket using 
    // Socket Class Costructor
    Socket listener = new Socket(ipAddr.AddressFamily,
                 SocketType.Stream, ProtocolType.Tcp);
  
    try {
          
        // Using Bind() method we associate a
        // network address to the Server Socket
        // All client that will connect to this 
        // Server Socket must know this network
        // Address
        listener.Bind(localEndPoint);
  
        // Using Listen() method we create 
        // the Client list that will want
        // to connect to Server
        listener.Listen(10);
  
        while (true) {
              
            Console.WriteLine("Waiting connection ... ");
  
            // Suspend while waiting for
            // incoming connection Using 
            // Accept() method the server 
            // will accept connection of client
            Socket clientSocket = listener.Accept();
  
            // Data buffer
            byte[] bytes = new Byte[1024];
            string data = null;
  
            while (true) {
  
                int numByte = clientSocket.Receive(bytes);
                  
                data += Encoding.ASCII.GetString(bytes,
                                           0, numByte);
                                             
                if (data.IndexOf("") > -1)
                    break;
            }
  
            Console.WriteLine("Text received -> {0} ", data);
            byte[] message = Encoding.ASCII.GetBytes("Test Server");
  
            // Send a message to Client 
            // using Send() method
            clientSocket.Send(message);
  
            // Close client Socket using the
            // Close() method. After closing,
            // we can use the closed Socket 
            // for a new Client Connection
            clientSocket.Shutdown(SocketShutdown.Both);
            clientSocket.Close();
        }
    }
      
    catch (Exception e) {
        Console.WriteLine(e.ToString());
    }
}
}
}

要在终端或命令提示符上运行:

  • 首先以.cs扩展名保存文件。假设我们将文件另存为client.csserver.cs
  • 然后通过执行以下命令来编译这两个文件:
    $ csc client.cs
    $ csc server.cs
  • 成功编译后,打开两个cmd,一个用于Server,另一个用于Client,然后首先尝试执行服务器,如下所示:

  • 之后,在另一个cmd上执行客户端代码,并在服务器端cmd上看到以下输出。

  • 现在,您可以在客户端程序执行后立即在服务器上看到更改。