多线程服务器

时间:2014-04-22 23:52:16

标签: c# multithreading sockets networkstream

我已经实现了一个服务器,现在我正在尝试使其成为多线程但是遇到了一个问题,即服务器在收到数据时失败并且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无法运作的原因,我将不胜感激。

1 个答案:

答案 0 :(得分:1)

在多线程的情况下,您可以比Close更快地调用DoRequest方法。

这是因为这两行都是最终阻止的。

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

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

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