Webserver works in a console app but not windows forms?
-
I have the following class:
public class WebServer
{
private readonly TcpListener _listener;
private readonly Thread _listenerThread;public WebServer() { \_listener = new TcpListener(IPAddress.Parse("127.0.0.1"), 80); \_listenerThread = new Thread(ListenForClients); } public void StartListening() { \_listenerThread.Start(); } private void ListenForClients() { \_listener.Start(); while (true) { TcpClient client = \_listener.AcceptTcpClient(); var clientThread = new Thread(HandleClient); clientThread.Start(client); } \_listener.Stop(); } private void HandleClient(object client) { var tcpClient = client as TcpClient; var clientStream = tcpClient.GetStream(); var encoder = new ASCIIEncoding(); var message = new byte\[4096\]; while (true) { int bytesRead = 0; string fileToGrab; try { //blocks until a client sends a message bytesRead = clientStream.Read(message, 0, 4096); string msg = encoder.GetString(message); Console.WriteLine("Client {0} connected", tcpClient.Client.LocalEndPoint); Console.WriteLine(msg); string\[\] parts = msg.Split(' '); fileToGrab = parts\[1\]; } catch { //a socket error has occured break; } if (bytesRead != 0) { if (fileToGrab == "/") fileToGrab = @"/index.html"; else if (!File.Exists(Environment.CurrentDirectory + fileToGrab)) { fileToGrab = @"/error.html"; } byte\[\] buffer = File.ReadAllBytes(Environment.CurrentDirectory + fileToGrab); clientStream.Write(buffer, 0, buffer.Length); clientStream.Flush(); string serverIp = "From server " + \_listener.LocalEndpoint; clientStream.Write(encoder.GetBytes(serverIp), 0, serverIp.Length); clientSt
-
I have the following class:
public class WebServer
{
private readonly TcpListener _listener;
private readonly Thread _listenerThread;public WebServer() { \_listener = new TcpListener(IPAddress.Parse("127.0.0.1"), 80); \_listenerThread = new Thread(ListenForClients); } public void StartListening() { \_listenerThread.Start(); } private void ListenForClients() { \_listener.Start(); while (true) { TcpClient client = \_listener.AcceptTcpClient(); var clientThread = new Thread(HandleClient); clientThread.Start(client); } \_listener.Stop(); } private void HandleClient(object client) { var tcpClient = client as TcpClient; var clientStream = tcpClient.GetStream(); var encoder = new ASCIIEncoding(); var message = new byte\[4096\]; while (true) { int bytesRead = 0; string fileToGrab; try { //blocks until a client sends a message bytesRead = clientStream.Read(message, 0, 4096); string msg = encoder.GetString(message); Console.WriteLine("Client {0} connected", tcpClient.Client.LocalEndPoint); Console.WriteLine(msg); string\[\] parts = msg.Split(' '); fileToGrab = parts\[1\]; } catch { //a socket error has occured break; } if (bytesRead != 0) { if (fileToGrab == "/") fileToGrab = @"/index.html"; else if (!File.Exists(Environment.CurrentDirectory + fileToGrab)) { fileToGrab = @"/error.html"; } byte\[\] buffer = File.ReadAllBytes(Environment.CurrentDirectory + fileToGrab); clientStream.Write(buffer, 0, buffer.Length); clientStream.Flush(); string serverIp = "From server " + \_listener.LocalEndpoint; clientStream.Write(encoder.GetBytes(serverIp), 0, serverIp.Length); clientSt
There's a simple way to test that: put [STAThread] on your console app. However, I'm fairly sure I've served TCP from within a WinForms app without problems in the past. I don't immediately see the problem. You should put some logging in the socket error catch block, as well as breaking out of the loop. Actually never mind that, you should use the asynchronous socket methods (BeginReceive and BeginAccept), instead of creating a thread for each client. (Also, your accept thread will never terminate.) Take a look at my Sockets library[^] for an example if the MSDN docs don't make it clear enough (specifically the ClientInfo class which uses asynchronous receive, and the Server class which uses asynchronous accept).