Witam,
Mam problem z aplikacją wątkową (aplikacja klient-serwer). Program po uruchomieniu i wystartowaniu wątku pracuje normalnie, ale w pewnym momencie (najczęściej po odłączeniu klienta od serwera) zaczyna obciążać w 100% processor… W przypadku 2,3 klientów robi się masakra… kod wygląda tak:
Plik glowny.sc:
namespace Serwer
{
class Program
{
static void Main(string[] args)
{
int sPort = 8081;
Hashtable klienci = new Hashtable();
try
{
IPAddress ip = IPAddress.Parse("192.168.0.1"); //169.254.27.49
TcpListener serwer = new TcpListener(ip, sPort);
serwer.Start();
Console.WriteLine("Serwer is started");
while (true)
{
TcpClient client = serwer.AcceptTcpClient();
Console.WriteLine("polaczono");
new Thread(new ThreadStart( new ConnectionSession(client).run)).Start();
}
}
catch (Exception see)
{
Console.WriteLine("Błąd : " + see.Message);
}
}
}
}
Plik ConnectionSession.cs:
class ConnectionSession
{
protected int ClientID = 0;
private TcpClient Client;
public ConnectionSession(TcpClient client)
{
Client = client;
}
public static int ByteIndexOf(byte[] searched, byte[] find, int start)
{
bool matched = false;
for (int index = start; index <= searched.Length - find.Length; ++index)
{
matched = true;
for (int subIndex = 0; subIndex < find.Length; ++subIndex)
{
if (find[subIndex] != searched[index + subIndex])
{
matched = false;
break;
}
}
if (matched)
{
return index;
}
}
return -1;
}
const int BUF_LEN = 256;
const int SYNC_FRAME_LEN = 8;
private bool ReadSynchroHeader()
{
byte[] myReadBuffer = new byte[BUF_LEN];
byte[] sync_frame = new byte[SYNC_FRAME_LEN];
int i;
for (i = 0; i < SYNC_FRAME_LEN; i++) {
sync_frame[i] = (byte)(i+0x80);
}
String s;
uint read_ptr = 0, write_ptr = 0;
if (Client.Connected)
{
StringBuilder dane = new StringBuilder();
int numberOfBytesRead = 0, numberOfBytesToRead = 0;
NetworkStream myNetworkStream = Client.GetStream();
while (Client.Connected)
{
try
{
if (myNetworkStream.CanRead)
{
numberOfBytesToRead = (int)(write_ptr >= read_ptr ? BUF_LEN - write_ptr : read_ptr - write_ptr);
myNetworkStream.ReadTimeout = 1000;
if (myNetworkStream.DataAvailable)
{
numberOfBytesRead = myNetworkStream.Read(myReadBuffer, (int)write_ptr, numberOfBytesToRead);
write_ptr = (uint)((write_ptr + numberOfBytesRead) % BUF_LEN);
}
while (read_ptr < write_ptr) {
if (myReadBuffer[read_ptr] == 0xFA || myReadBuffer[read_ptr] == '$') {
break;
}
read_ptr = (read_ptr + 1) % BUF_LEN;
}
if (read_ptr == write_ptr) {
read_ptr = write_ptr = 0;
continue;
}
try
{
if (myReadBuffer[read_ptr] == 0xFA)
{
if ((write_ptr - read_ptr + BUF_LEN) % BUF_LEN < SYNC_FRAME_LEN)
{
continue;
}
for (i = 0; i < SYNC_FRAME_LEN; i++)
{
sync_frame[i] = myReadBuffer[(read_ptr + i) % BUF_LEN];
}
if (sync_frame[1] != 0xF8)
{
s = "";
for (i = 0; i < SYNC_FRAME_LEN; i++) {
s += String.Format("{0:X2} ", sync_frame[i]);
}
throw new FormatException("RE01 "+s);
}
int syncID = myReadBuffer[(read_ptr + 2) % BUF_LEN] | (myReadBuffer[(read_ptr + 3) % BUF_LEN] << 8);
uint unitID = (uint)myReadBuffer[(read_ptr + 4) % BUF_LEN] | (uint)(myReadBuffer[(read_ptr + 5) % BUF_LEN]) << 8 |
(uint)(myReadBuffer[(read_ptr + 6) % BUF_LEN]) << 16 | (uint)(myReadBuffer[(read_ptr + 7) % BUF_LEN]) << 24;
Console.WriteLine(String.Format("Odebrano sync: {0:X4}, UnitID {1:X8}\r\n", syncID, unitID));
SendMessage(sync_frame, SYNC_FRAME_LEN);
// przesuń wskaźnik odczytu (cała ramka odczytana)
read_ptr = (read_ptr + SYNC_FRAME_LEN) % BUF_LEN;
}
else if (myReadBuffer[read_ptr] == '$' || (myReadBuffer[read_ptr] >= '0' && myReadBuffer[read_ptr] <= '9'))
{
uint ptr = read_ptr+1;
while (ptr < write_ptr)
{
if (myReadBuffer[ptr] == '\n')
{
break;
}
else if (myReadBuffer[ptr] == '$') {
s = "";
for (i = 0; i < ptr - read_ptr + 5; i++) {
s += String.Format("{0:X2} ", myReadBuffer[(read_ptr + i)%BUF_LEN]);
}
throw new FormatException("RE04 " + s);
}
ptr = (ptr + 1) % BUF_LEN;
}
if (ptr == write_ptr)
{
continue;
}
byte[] buf = new byte[256];
byte[] b = Encoding.ASCII.GetBytes("Odebrano ramkę: ");
for (i = 0; i < b.Length; i++)
{
buf[i] = b[i];
}
for (i = 0; i < (write_ptr - read_ptr + BUF_LEN) % BUF_LEN; i++)
{
buf[16 + i] = myReadBuffer[(read_ptr + i) % BUF_LEN];
}
SendMessage(buf, i + 16);
read_ptr = (ptr + 1) % BUF_LEN;
}
}
catch (FormatException ex) {
read_ptr = (read_ptr + 1) % BUF_LEN;
}
}
}
catch (Exception se)
{
Console.WriteLine("Klient odłączony");
}
}
}
else
{
Console.WriteLine("Klient odłączony");
}
return true;
}
public static byte[] StrToByteArray(string str)
{
System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
return encoding.GetBytes(str);
}
private void ReadInfo()
{
if (Client.Connected)
{
StreamReader rclient = new StreamReader(Client.GetStream());
while (true)
{
try
{
string dane = rclient.ReadLine();
Console.WriteLine(dane);
}
catch (Exception se)
{
Console.WriteLine("Błąd : " + se.Message);
}
}
}
}
private void SendMessage(string message)
{
if (String.IsNullOrEmpty(message))
message = "\n";
byte[] metaBuffer = Encoding.ASCII.GetBytes(message);
Console.WriteLine("Sending:" + message);
}
private void SendMessage(byte[] message, int len)
{
if (Client.Connected)
{
NetworkStream wclient = Client.GetStream();
try
{
Console.WriteLine("Wysłalem:'" + Encoding.ASCII.GetString(message));
wclient.Write(message, 0, len);
wclient.Flush();
}
catch (Exception se)
{
Console.WriteLine("Błąd : " + se.Message);
}
}
}
public void run()
{
ReadSynchroHeader();
}
}
Wiecie może jak to zoptymalizować??
Z góry dzięki WIELKIE za pomoc:))
Pozdrawiam Northwest