【问题标题】:Multi Threaded Server多线程服务器
【发布时间】:2014-04-22 23:52:15
【问题描述】:

我已经实现了一个服务器,现在正试图使其成为多线程,但是遇到了一个问题,即服务器在接收到数据时失败,并且StreamWriter 无法从Stream 读取数据。

代码如下:

class whereisServer
{
    static Socket connection;
    static object threadLock = new object();

    static void Main(string[] args)
    {
        Thread t = new Thread(new ThreadStart(Run));
        t.Start();
    }

    static void Run()
    {
        NetworkStream socketStream;
        TcpListener listener;
        const int PORT = 43;
        try
        {
            listener = new TcpListener(IPAddress.Any, PORT);
            listener.Start();
            while (true)
            {
                connection = listener.AcceptSocket();
                socketStream = new NetworkStream(connection);
                try
                {
                    connection.ReceiveTimeout = 1000;
                    connection.SendTimeout = 1000;
                    Thread t = new Thread(new ParameterizedThreadStart(DoRequest));
                    t.Start(socketStream);
                    //DoRequest(socketStream);
                }
                catch (IOException e)
                {
                    Console.WriteLine(e.Message + "\nTimeOut Handled");
                }
                finally
                {
                    socketStream.Close();
                    connection.Close();
                }
            }
        }
        catch (SocketException e)
        {
            Console.WriteLine(e.Message);
        }
    }

    static void DoRequest(object stream)
    {
        NetworkStream socketStream = (NetworkStream)stream;
        StreamWriter writer = new StreamWriter(socketStream);
        StreamReader reader = new StreamReader(socketStream);

        lock (threadLock)
        {
             //DO SERVER STUFF HERE
        }

当在没有线程的情况下调用DoRequest 方法时,程序运行良好,但是当将其注释掉并调用线程版本时,就会出现问题。

如果有人能就Stream 无法运行的原因提出建议,我将不胜感激。

【问题讨论】:

  • 如果您向我们提供错误信息会有所帮助。否则我们只能猜测问题所在。
  • 异常说“流不可写。此外,它说我的 StreamWriter 和 StreamReader 等于 null,尽管我已经创建了它们。虽然当我不使用线程时,这段代码工作正常.

标签: c# multithreading sockets networkstream


【解决方案1】:

在多线程情况下,您调用 Close 方法比 DoRequest 更早完成它的工作。

因为这两行在 finally 块中。

socketStream.Close();
connection.Close();

这两行在Start 方法启动新线程之后立即执行,但在该线程完成其在DoRequest 中的工作之前。

我建议您在 DoRequest 中调用这些方法。您可以将connection 对象传递给DoRequest,然后在DoRequest 内部创建socketStream,完成后,在完成DoRequest 方法之前关闭这两个对象。 (或者您可以使用任何其他解决方案,这只是一种选择。)

【讨论】:

  • 谢谢,除了我只能通过 Thread 上的 Start 方法传递一个参数,我目前正在传递 NetworkStream。您如何建议关闭 DoRequest 方法中的连接。谢谢
  • 你可以在 DoRequest 中使用 try-finally。
  • 好的,谢谢,我已经能够实现这个了,但是自从我开始使用线程版本后,我的 DoRequest 方法就无法正常工作了。当从客户端输入时,预计会更新一个人的位置,但现在不会了。我的 DoRequest 方法可以在这里找到:codeshare.io/ZQpgy
猜你喜欢
  • 2014-04-24
  • 2015-08-11
  • 2019-01-20
  • 2019-05-27
  • 2015-02-10
  • 2014-03-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多