【问题标题】:Respond to a client using a socket?使用套接字响应客户端?
【发布时间】:2013-10-23 16:16:43
【问题描述】:

我有两个基本的控制台应用程序“通过网络”进行通信,即使所有通信都发生在我的本地计算机上。

客户端代码:

public static void Main()
{
    while (true)
    {
        try
        {
            TcpClient client = new TcpClient();

            client.Connect("127.0.0.1", 500);

            Console.WriteLine("Connected.");

            byte[] data = ASCIIEncoding.ASCII.GetBytes(new FeederRequest("test", TableType.Event).GetXmlRequest().ToString());

            Console.WriteLine("Sending data.....");

            using (var stream = client.GetStream())
            {
                stream.Write(data, 0, data.Length);
                stream.Flush();

                Console.WriteLine("Data sent.");
            }

            client.Close();

            Console.ReadLine();
        }
        catch (Exception e)
        {
            Console.WriteLine("Error: " + e.StackTrace);

            Console.ReadLine();
        }
    }
}

服务器代码:

public static void Main()
{
    try
    {
        IPAddress ipAddress = IPAddress.Parse("127.0.0.1");

        Console.WriteLine("Starting TCP listener...");

        TcpListener listener = new TcpListener(ipAddress, 500);

        listener.Start();

        Console.WriteLine("Server is listening on " + listener.LocalEndpoint);

        while (true)
        {
            Socket client = listener.AcceptSocket();

            Console.WriteLine("\nConnection accepted.");

            var childSocketThread = new Thread(() =>
                {
                    Console.WriteLine("Reading data...\n");

                    byte[] data = new byte[100];
                    int size = client.Receive(data);
                    Console.WriteLine("Recieved data: ");
                    for (int i = 0; i < size; i++)
                        Console.Write(Convert.ToChar(data[i]));

                    //respond to client


                    Console.WriteLine("\n");

                    client.Close();

                    Console.WriteLine("Waiting for a connection...");
                });

            childSocketThread.Start();
        }
    }
    catch (Exception e)
    {
        Console.WriteLine("Error: " + e.StackTrace);
        Console.ReadLine();
    }
}

如何更改这两个应用程序,以便在服务器收到数据时,它会以某种确认方式响应客户端?

提前致谢!

【问题讨论】:

  • 到目前为止,您尝试过什么样的事情? :)
  • 您可以使用 BinaryReader/Writer 来读取和写入流。我在下面发布了一个示例。希望对回答您的问题有所帮助。

标签: c# .net sockets tcpclient tcplistener


【解决方案1】:

下面是一个简短的例子:

服务器:

class Server
    {
        static void Main(string[] args)
        {
            TcpListener listener = new TcpListener(IPAddress.Any, 1500);
            listener.Start();

            TcpClient client = listener.AcceptTcpClient();

            NetworkStream stream = client.GetStream();

            // Create BinaryWriter for writing to stream
            BinaryWriter binaryWriter = new BinaryWriter(stream);

            // Creating BinaryReader for reading the stream
            BinaryReader binaryReader = new BinaryReader(stream);

            while (true) 
            {
                // Read incoming information
                byte[] data = new byte[16];
                int receivedDataLength = binaryReader.Read(data, 0, data.Length);
                string stringData = Encoding.ASCII.GetString(data, 0, receivedDataLength);

                // Write incoming information to console
                Console.WriteLine("Client: " + stringData);

                // Respond to client
                byte[] respondData = Encoding.ASCII.GetBytes("respond");
                Array.Resize(ref respondData, 16); // Resizing to 16 byte, because in this example all messages have 16 byte to make it easier to understand.
                binaryWriter.Write(respondData, 0, 16);
            }

        }
    }

客户:

class Client
    {
        private static void Main(string[] args)
        {
            Console.WriteLine("Press any key to start Client");
            while (! Console.KeyAvailable)
            {
            }


            TcpClient client = new TcpClient();
            client.Connect("127.0.0.1", 1500);

            NetworkStream networkStream = client.GetStream();

            // Create BinaryWriter for writing to stream
            BinaryWriter binaryWriter = new BinaryWriter(networkStream);

            // Creating BinaryReader for reading the stream
            BinaryReader binaryReader = new BinaryReader(networkStream);

            // Writing "test" to stream
            byte[] writeData = Encoding.ASCII.GetBytes("test");
            Array.Resize(ref writeData, 16); // Resizing to 16 byte, because in this example all messages have 16 byte to make it easier to understand.
            binaryWriter.Write(writeData, 0, 16);

            // Reading response and writing it to console
            byte[] responeBytes = new byte[16];
            binaryReader.Read(responeBytes, 0, 16);
            string response = Encoding.ASCII.GetString(responeBytes);
            Console.WriteLine("Server: " + response);


            while (true)
            {
            }
        }
    }

我希望这会有所帮助! ;)

【讨论】:

    【解决方案2】:

    您可以在同一个流上同时执行读取和写入。 发送完所有数据后,只需调用 stream.Read as in

            using (var stream = client.GetStream())
            {
                stream.Write(data, 0, data.Length);
                stream.Flush();
    
                Console.WriteLine("Data sent.");
    
                stream.Read(....); //added sync read here                
            }
    

    关于 TcpClient 的 MSDN 文档也有一个示例 http://msdn.microsoft.com/en-us/library/system.net.sockets.tcpclient.aspx

    如果您想要反馈,例如报告到目前为止收到的字节数,您必须使用异步方法。

    【讨论】:

      【解决方案3】:

      这是你想要做的(我认为)的一个例子:

          static void Main(string[] args) {
              var server = new Task(Server);
              server.Start();
              System.Threading.Thread.Sleep(10); // give server thread a chance to setup
              try {
                  TcpClient client = new TcpClient();
                  client.Connect("127.0.0.1", 1500);
                  Console.WriteLine("Connected.");
                  var data = new byte[100];
                  var hello = ASCIIEncoding.ASCII.GetBytes("Hello");
                  Console.WriteLine("Sending data.....");
                  using (var stream = client.GetStream()) {
                      stream.Write(hello, 0, hello.Length);
                      stream.Flush();
                      Console.WriteLine("Data sent.");
                      // You could then read data from server here:
                      var returned = stream.Read(data, 0, data.Length);
                      var rec = new String(ASCIIEncoding.ASCII.GetChars(data, 0, data.Length));
                      rec = rec.TrimEnd('\0');
                      if (rec == "How are you?") {
                          var fine  = ASCIIEncoding.ASCII.GetBytes("fine and you?");
                          stream.Write(fine, 0, fine.Length);
                          }
                      }
                  client.Close();
                  Console.ReadLine();
                  }
              catch (Exception e) {
                  Console.WriteLine("Error: " + e.StackTrace);
                  Console.ReadLine();
                  }
              }
      
          public static void Server() {
              try {
                  IPAddress ipAddress = IPAddress.Parse("127.0.0.1");
                  Console.WriteLine("*Starting TCP listener...");
                  TcpListener listener = new TcpListener(ipAddress, 1500); // generally use ports > 1024
                  listener.Start();
                  Console.WriteLine("*Server is listening on " + listener.LocalEndpoint);
                  Console.WriteLine("*Waiting for a connection...");
                  while (true) {
                      Socket client = listener.AcceptSocket();
                      while (client.Connected) {
                          Console.WriteLine("*Connection accepted.");
                          Console.WriteLine("*Reading data...");
                          byte[] data = new byte[100];
                          int size = client.Receive(data);
                          Console.WriteLine("*Recieved data: ");
                          var rec = new String(ASCIIEncoding.ASCII.GetChars(data, 0, size));
                          rec = rec.TrimEnd('\0');
                          Console.WriteLine(rec);
                          if (client.Connected == false) {
                              client.Close();
                              break;
                              }
                          // you would write something back to the client here
                          if (rec == "Hello") {
                              client.Send(ASCIIEncoding.ASCII.GetBytes("How are you?"));
                              }
                          if (rec == "fine and you?") {
                              client.Disconnect(false);
                              }
                          }
                      }
                  listener.Stop();
                  }
              catch (Exception e) {
                  Console.WriteLine("Error: " + e.StackTrace);
                  Console.ReadLine();
                  }
              }
          }
      

      请记住,通过套接字发送的数据可能会分段到达(在不同的数据包中)。这通常不会发生在数据包很小的情况下。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-05-23
        • 2015-03-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-11-21
        • 1970-01-01
        相关资源
        最近更新 更多