Reputation: 13
I have searched many examples and tutorials and what not but I cant for the life of me figure out what im doing wrong here... If I send several messages to this server I made only the first is printed in the Console.Writeline command and the rest is never printed... I must be doing something fundametally wrong but I really cant find it ... :S
This is the server code:
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Windows.Forms.VisualStyles;
namespace HL7_Manager
{
public class MonitorServer
{
private int _port;
private Socket _serverSocket;
private List<ClientObject> _clients;
public bool IsConnected { get; set; }
public MonitorServer(int port)
{
_port = port;
_clients = new List<ClientObject>();
}
public void StartListening()
{
_serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
Thread listenThread = new Thread(new ThreadStart(ListenerThread));
listenThread.IsBackground = true;
listenThread.Start();
}
public void StopListening()
{
IsConnected = true;
_serverSocket.Close();
while (_clients.Count > 0)
{
_clients[0].KeepProcessing = false;
_clients[0].ClientSocket.Close();
_clients.RemoveAt(0);
}
}
private void ListenerThread()
{
_serverSocket.Bind(new IPEndPoint(IPAddress.Any, _port));
_serverSocket.Listen(100);
Console.WriteLine("Listening on port 8000");
while (true)
{
Socket clientSocket = _serverSocket.Accept();
ClientObject client = new ClientObject();
client.KeepProcessing = true;
client.ClientSocket = clientSocket;
_clients.Add(client);
ParameterizedThreadStart ptStart = new ParameterizedThreadStart(ProcessClientThread);
Thread processThread = new Thread(ptStart);
processThread.IsBackground = true;
processThread.Start(client);
clientSocket = null;
client = null;
}
}
private void ProcessClientThread(object clientObj)
{
Console.WriteLine("Client connected");
ClientObject client = (ClientObject) clientObj;
Socket clientSocket = client.ClientSocket;
byte[] buffer = new byte[clientSocket.ReceiveBufferSize];
int receiveCount = 0;
while (client.KeepProcessing)
{
try
{
receiveCount = clientSocket.Receive(buffer, 0, buffer.Length, SocketFlags.None);
Console.WriteLine(Encoding.ASCII.GetString(buffer));
}
catch (Exception ex)
{
if (!client.KeepProcessing)
return;
Console.WriteLine(ex.Message);
}
}
clientSocket.Close();
_clients.Remove(client);
}
}
}
Upvotes: 0
Views: 1372
Reputation: 7467
Check how many bytes you really received. TCP is a streaming protocol this means that if you client is doing several sends of small messages right one after the other, you will receive them in one go at the receiver. If there happens to be a null character in your receive buffer you might think you did not receive all those string, but actually you did. Check this by inspecting how many bytes you received and by checking the buffer content. If you made this mistake there might be some deeper problem in your code. The fact that TCP is streaming makes it a bit more complex
Upvotes: 0
Reputation: 92
Here is the method you should definitely change and how to change it.
private void ProcessClientThread(object clientObj)
{
Console.WriteLine("Client connected");
ClientObject client = (ClientObject)clientObj;
Socket clientSocket = client.ClientSocket;
byte[] buffer = new byte[clientSocket.ReceiveBufferSize];
int receiveCount = 0;
while (client.KeepProcessing)
{
try
{
receiveCount = clientSocket.Receive(buffer, 0, buffer.Length, SocketFlags.None);
if (receiveCount == 0)
break; //the client has closed the stream
var ret = Encoding.ASCII.GetString(buffer, 0, receiveCount);
Console.WriteLine(ret);
}
catch (Exception ex)
{
if (!client.KeepProcessing)
return;
Console.WriteLine(ex.Message);
}
}
clientSocket.Close();
_clients.Remove(client);
}
Upvotes: 1