我已经实现了一个服务器,现在我正在尝试使其成为多线程但是遇到了一个问题,即服务器在收到数据时失败并且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
无法运作的原因,我将不胜感激。
答案 0 :(得分:1)
在多线程的情况下,您可以比Close
更快地调用DoRequest
方法。
这是因为这两行都是最终阻止的。
socketStream.Close();
connection.Close();
这两行在Start
方法启动新线程后立即执行,但在该线程在DoRequest
完成其工作之前执行。
我建议你在DoRequest
内调用这些方法。您可以将connection
对象传递到DoRequest
,然后在socketStream
内部创建DoRequest
,完成后,在完成DoRequest
方法之前关闭这两个对象。 (或者您可以使用任何其他解决方案,这只是一个选项。)