如何通过套接字发送多个消息

3
我是一名有用的助手,可以为您进行文本翻译。

我在互联网上看到了如何在C#中创建套接字服务器的方法,
发送一条消息到服务器后,服务器就会关闭。
我一直在想,我该怎么改变它,让它能够处理多条消息。

代码:

static void startServer() {
    Console.WriteLine("[*] Opening server...");
    TcpListener listener = new TcpListener(IPAddress.Any, 45784);
    listener.Start();
    Console.WriteLine("[*] Server waiting on port " + 45784);
    TcpClient client = listener.AcceptTcpClient();
    Console.WriteLine("Client connected!");

    StreamReader STR = new StreamReader(client.GetStream());
    Console.WriteLine(STR.ReadLine());
}
static void Main(string[] args)
    {
        string ip = GetIpAdress();
        Console.WriteLine("server on: " + ip);
        startServer();
        Console.Read();
    }

服务器应用程序正在退出吗?通常,服务器必须添加一个块,以便程序不会退出。我无法判断 main() 函数是否在结束服务器。 - jdweng
我有一个主函数,它启动了这个函数(我没有想到这是必要的)。 - ronald7894
请详细说明,您是指“多行消息”还是“来自多个客户端的每条消息”? - Thariq Nugrohotomo
我是指来自单个客户端的连续多条消息。 - ronald7894
方法startServer()在返回时将处理所有资源,这将关闭服务器(监听器)。为了使代码正常工作,您需要将listener和client的定义移动到startServer方法之外的全局空间或在startServer函数内部循环,以便它不会返回。 - jdweng
3个回答

0

你的服务器在接收到一条消息后停止了,因为这是你告诉它要做的(目前为止)。

这些行:

StreamReader STR = new StreamReader(client.GetStream());
Console.WriteLine(STR.ReadLine());

将处理来自客户端的一条消息,然后停止,因为您没有告诉它获取另一条消息。

如果您希望服务器侦听和处理任意数量的消息,则需要将此代码放入循环中。

尝试这个:

static TcpListener StartServer()
{
    Console.WriteLine("[*] Opening server...");
    TcpListener listener = new TcpListener(IPAddress.Any, 45784);
    listener.Start();
    Console.WriteLine("[*] Server waiting on port " + 45784);

    return listener;
}

static void Listen(CancellationToken cancellationToken)
{
    string ip = GetIpAddress();
    Console.WriteLine("server on: ");
    var listener = StartServer();

    var client = listener.AcceptTcpClient();
    Console.WriteLine("Client connected!");

    var reader = new StreamReader(client.GetStream());

    while (!cancellationToken.IsCancellationRequested)
    {
        Console.WriteLine(reader.ReadLine());
    }
}

static void Main(string[] args)
{
    var cancellationSource = new CancellationTokenSource();

    Console.CancelKeyPress += (s, e) =>
    {
        e.Cancel = true;
        cancellationSource.Cancel();
    };

    Listen(cancellationSource.Token);
}

这段代码将持续从远程客户端获取行,直到使用 Ctrl-C 取消服务器。它使用 CancellationToken 来挂钩取消事件,但如果需要的话,也可以使用 bool 标志。

注意事项:此代码仅接受来自单个客户端的消息,而不是多个客户端(这是不同的挑战)。此外,一旦发送了取消事件,服务器会在退出并关闭连接之前等待客户端发送一条更多的消息,因为 ReadLine() 会阻塞线程,直到看到消息进来。


0
我是说,来自单个客户端的多条消息,一个接一个地发送。
你需要添加一些循环。
listener.Start();
while(true) {       // beware: please avoid never-ending loop, and define a proper exit condition
    TcpClient client = listener.AcceptTcpClient();
    using(client) {
        Console.WriteLine("Client connected!");

        StreamReader STR = new StreamReader(client.GetStream());
        string s = STR.ReadLine();
        while(s != null) { // read until EOF
            Console.WriteLine(s);
        }
    }
}
listener.Stop();    // this should always be called after exit condition occurs

0

我相信这很基础。简单来说,你的代码只读取一条消息并退出。

要读取多个消息,你只需要在这行代码周围加上一个 while 循环。

Console.WriteLine(STR.ReadLine());

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接