Здравствуйте! Tcp клиент реализован в виде службы, а сервер в виде консольного приложения. Служба запускается и идет запись в логи. При первом срабатывании таймера все проходит успешно (клиент каждые 20 с отправляет необх инфо серверу), а при втором срабатывании таймера данные формируются, но в методе Receive (получение ответа от сервера) возникает исключение "Программа на вашем хост-компьютере разорвала установленное подключение"(при этом в методе Send почему-то исключения не возникло, но сервер при этом никак не отреагировал на это (никаких исключений). Затем, при последующих попытках, на стороне клиента уже в методах Send возникали исключения "Программа на вашем хост-компьютере разорвала установленное подключение". И все... Подскажите, пожалуйста, в чем может быть причина. Какие особенности работы службы с сетевыми подключениями я не учитываю? Спасибо. Служба Код | public class DriversService : System.ServiceProcess.ServiceBase { private System.Diagnostics.EventLog eventLog;
private System.ComponentModel.Container components = null;
private SignalsCollector signalsCollector;
private static WindowsPC windowsPCcollector = new WindowsPC(); private static bool connectionEstablished = false;
public DriversService() { this.ServiceName = "DriversService"; this.CanStop = true; this.CanPauseAndContinue = false; this.AutoLog = false;
InitializeComponent();
if (!System.Diagnostics.EventLog.SourceExists("DriversServiceSourse")) { System.Diagnostics.EventLog.CreateEventSource("DriversServiceSourse", "DriversServiceLog"); }
eventLog.Source = "DriversServiceSourse"; eventLog.Log = "DriversServiceLog"; do { try { signalsCollector = new SignalsCollector(); connectionEstablished = true; } catch (Exception e) { Functions.WriteTrace("signalCollector timeout 2 min"); Thread.Sleep(120000); connectionEstablished = false; } } while (!connectionEstablished); }
public static bool iAmAlive = true;
public static NetSocketClient sender = null;
static void Main(string[] args) { Trace.Listeners.Add(new EventLogTraceListener("DriversServiceSourse")); Trace.AutoFlush = true; Functions.WriteTrace("Drivers service started. Press Enter for Exit"); System.ServiceProcess.ServiceBase[] ServicesToRun; ServicesToRun = new System.ServiceProcess.ServiceBase[] { new DriversService() }; System.ServiceProcess.ServiceBase.Run(ServicesToRun); }
private void InitializeComponent() { this.eventLog = new System.Diagnostics.EventLog(); ((System.ComponentModel.ISupportInitialize)(this.eventLog)).BeginInit(); this.eventLog.Log = "DriversServiceLog"; this.eventLog.Source = "DriversServiceSource"; this.ServiceName = "DriversService"; ((System.ComponentModel.ISupportInitialize)(this.eventLog)).EndInit(); }
protected override void Dispose(bool disposing) { if (disposing && components != null) { components.Dispose(); } base.Dispose(disposing); }
protected override void OnStart(string[] args) { eventLog.WriteEntry("my service started");
signalsCollector.Start(); }
protected override void OnStop() { eventLog.WriteEntry("my service stoped");
signalsCollector.Stop(); iAmAlive = false; }
protected override void OnContinue() { eventLog.WriteEntry("my service is continuing working"); } }
|
SignalCollector.cs Код | public class SignalsCollector { private Timer timer; private string config = @"D:\...\configuration.xml"; private Drivers.WindowsPC winPC; private NetSocketClient senderTcp = null;
public SignalsCollector() { winPC = new Drivers.WindowsPC(); try { senderTcp = new NetSocketClient(config); senderTcp.Connect(); } catch (Exception e) { Functions.WriteTrace(e.ToString()); return; } }
public void Start() { this.timer = new System.Timers.Timer(); this.timer.Enabled = true; this.timer.Interval = 20000; this.timer.Elapsed += new ElapsedEventHandler(this.Collect); this.timer.AutoReset = true; this.timer.Start(); }
public void Stop() { this.timer.Stop(); this.timer = null; }
private void Collect(object sender, ElapsedEventArgs args) { this.timer.Enabled = false; string datastring = string.Empty; try { List<Signal> signals = winPC.GetState(); datastring = Signal.JSONSerializer(signals); Functions.WriteTrace(string.Concat("Сокет соединяется с ", senderTcp.socket.RemoteEndPoint.ToString())); int bytesSent = senderTcp.Send(Encoding.UTF8.GetBytes(datastring));
Functions.WriteTrace(string.Format("Отправлено: {0}\n\n", datastring));
int bytesRec = senderTcp.Receive();// Получаем ответ от сервера
string message = Encoding.UTF8.GetString(senderTcp.Buffer, 0, bytesRec); Functions.WriteTrace(string.Concat("Ответ от сервера: ", message));
if (message.IndexOf("End") > -1) { senderTcp.Free(); return; } } catch (SocketException e) { Functions.WriteTrace(e.ToString()); Functions.WriteTrace(string.Concat("Не удается соединиться по указанному адресу ", senderTcp.Addr)); return; } finally { this.timer.Enabled = true; } } }
|
NetSocketClient.cs Код | public class NetSocketClient { public Socket socket;
IPEndPoint ipEndPoint;
public string Addr { get {return ipEndPoint.ToString(); } }
byte[] bytes; // Буфер для входящих данных
public byte[] Buffer { get { return bytes; } }
public NetSocketClient(string xml) { XmlDocument xd = new XmlDocument(); FileStream fs = new FileStream(xml, FileMode.Open); xd.Load(fs);
int port = 0; string localIP = Functions.LocalIPAddress(), mqBoxIP; IPAddress remoteIP;
if (xd.GetElementsByTagName("Port").Count == 0 || xd.GetElementsByTagName("RemoteIP").Count == 0 || !int.TryParse(((XmlElement)xd.GetElementsByTagName("Port")[0]).InnerText, out port) || string.IsNullOrEmpty(mqBoxIP = ((XmlElement)xd.GetElementsByTagName("RemoteIP")[0]).InnerText) || !IPAddress.TryParse(mqBoxIP, out remoteIP)) { Functions.WriteTrace("IP адрес или номер порта отсутствуют в файле configuration.xml."); throw new Exception(); } else { port = port + ((IPAddress.Parse(localIP)).GetAddressBytes())[3]; ipEndPoint = new IPEndPoint(remoteIP, port); socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); } fs.Close(); }
public void Connect() { socket.Connect(ipEndPoint); }
public int Send(byte[] buffer) { return socket.Send(buffer); }
public int Receive() { bytes = new byte[socket.ReceiveBufferSize]; return socket.Receive(bytes); }
public void Free() { socket.Shutdown(SocketShutdown.Both); socket.Close(); } }
|
P.S., Когда клиент был реализован в виде консольного приложения, все работало исправно. Вся беда была в sListener.Accept и handler.Close. Закрывать handler не надо было, а Accept выполнить 1 раз за пределами while (true) в серверной части. Это сообщение отредактировал(а) Zerofill - 7.11.2013, 12:51
|