【问题标题】:C# TCP client connect to serverC# TCP 客户端连接到服务器
【发布时间】:2019-06-18 02:20:23
【问题描述】:

我正在研究服务器和多个客户端之间的主从网络关系。 服务器很好,问题是我是 TCP 新手,不知道如何在客户端不知道 ip 的情况下连接到服务器。

如果有人可以重写我的一些代码使其正常工作,我将不胜感激。

服务器

namespace Server
{
class Program
{
    static void Main(string[] args)
    {
        TcpListener listen = new TcpListener(IPAddress.Any, 8001);
        TcpClient clientSocket = default(TcpClient);
        int counter = 0;

        listen.Start();
        Console.WriteLine(" >> " + "Server Started");

        while (true)
        {
            counter += 1;
            clientSocket = listen.AcceptTcpClient();
            HandleClinet client = new HandleClinet();
            client.startClient(clientSocket, Convert.ToString(counter));
        }
    }
}

public class HandleClinet
{
    TcpClient clientSocket;
    string clNo;
    public void startClient(TcpClient inClientSocket, string clineNo)
    {
        clientSocket = inClientSocket;
        clNo = clineNo;
        Thread ClientThread = new Thread(DoChat);
        ClientThread.Start();
    }
    private void DoChat()
    {
        byte[] bytesFrom = new byte[1024];
        string dataFromClient = null;
        byte[] sendBytes = null;
        string serverResponse = null;

        while ((true))
        {
            try
            {
                NetworkStream networkStream = clientSocket.GetStream();

                networkStream.Read(bytesFrom, 0, 1024);
                dataFromClient = Encoding.ASCII.GetString(bytesFrom);
                dataFromClient = dataFromClient.Substring(0, dataFromClient.IndexOf("\0"));
                Console.WriteLine(" >> " + "From client-" + clNo + " " + dataFromClient);

                serverResponse = Console.ReadLine();
                sendBytes = Encoding.ASCII.GetBytes(serverResponse);
                networkStream.Write(sendBytes, 0, sendBytes.Length);

                networkStream.Flush();
            }
            catch (Exception ex)
            {
                throw;
            }
        }
    }
}
}

客户

namespace Client
{
class Program
{
    public static TcpClient tcpclnt = new TcpClient();

    static void Main(string[] args)
    {
        while(true)
        {
            LoopConnect();
            LoopPacket();
            tcpclnt.Close();
        }
    }

    private static void LoopPacket()
    {
        byte[] bytesFrom = new byte[1024];
        string dataFromClient = null;
        byte[] sendBytes = null;
        string serverResponse = null;

        while ((true))
        {
            try
            {
                NetworkStream networkStream = tcpclnt.GetStream();

                serverResponse = "Give me a command!";
                sendBytes = Encoding.ASCII.GetBytes(serverResponse);
                networkStream.Write(sendBytes, 0, sendBytes.Length);

                networkStream.Read(bytesFrom, 0, 1024);
                dataFromClient = Encoding.ASCII.GetString(bytesFrom);
                dataFromClient = dataFromClient.Substring(0, dataFromClient.IndexOf("\0"));
                Console.WriteLine(" >> " + "From server -" + dataFromClient);
                networkStream.Flush();
            }
            catch (Exception ex)
            {
                throw;
            }
        }
    }

    private static void LoopConnect()
    {
        Console.WriteLine("Connecting.....");
        while(true)
        {
            try
            {
                tcpclnt.Connect(IPAddress.Any, 8001); // The problem area
                break;
            }
            catch (Exception)
            {
                Console.Write(".");
            }
        }
        Console.WriteLine("Connected.");
    }
}
}

【问题讨论】:

  • 附注 - 你的代码有一个严重的问题 - Read 返回它放置在缓冲区中的字节数。你无法保证,即使你请求 1024 字节,而对方已经发送了 1024 字节或更多,它也会向你提供 1024 字节。
  • @Damien_The_Unbeliever 应该是文本应用,这里的包不是问题
  • 我们这里不是在讨论数据包。 TCP 提供的全部是双向的无穷无尽的字节流。如果您想要“消息传递”,则由 在无穷无尽的字节流上实现它,或者转移到构建在 TCP 之上的更高级别的协议,该协议实现消息传递(可能还有其他事情)你。

标签: c# windows sockets networking tcp


【解决方案1】:

客户端应该以某种方式获取服务器的地址。该方法取决于网络类型(本地或 Internet)。在 Internet 的情况下,没有一些已知的对等点几乎是不可能的。如果是本地网络,您可以使用广播 UDP 请求(此方法取决于本地网络路由规则)。

【讨论】:

  • 这将是一个仅限 LAN 的应用程序。我可以让主机创建带有 ip 的客户端 exe,而不是将其传递给每个人,但是如果路由器重新启动并且地址混淆了怎么办?有没有办法遍历网络上存在的所有 IP 地址? (用于家庭使用,所以应该不是问题)
  • @HegyAlpha - 通常在一个受控良好的网络上,您将 a) 为您的服务器分配静态 IP 地址和 b) 让 DNS 可用于分配 names 客户端可以绑定而不是 IP 地址(对于 b,如果 a 没有发生,它应该是某种形式的动态 DNS)
  • @HegyAlpha 如果这只是局域网,那么使用 UDP 广播的方法将是一种更可取的方法。尽管 LAN 路由器应该允许广播流量。如果您的客户端和服务器位于同一网段内,并且它们之间没有任何网关,那么您根本不会有任何问题。
  • @montonero 谢谢,我会研究一下 UDP 方法。
  • @Damien_The_Unbeliever 因为不知道它会是什么样的服务器/客户端,所以一般来说它不能依赖任何名称。 IE。这些“服务器”和“客户端”可以在网络中的任何机器上运行,而不仅仅是在某些专用服务器机器上。
猜你喜欢
  • 1970-01-01
  • 2015-08-21
  • 2021-08-12
  • 2022-01-16
  • 2019-06-06
  • 2017-02-24
  • 1970-01-01
  • 2012-07-04
  • 1970-01-01
相关资源
最近更新 更多