2014-10-01 92 views
0

我的问题只发生在我尝试在Windows服务下使用套接字连接时。 基本上我有一个连接到远程服务器的套接字客户端。 当我在客户端应用程序中使用它时,我根本没有任何问题。 但是,当我尝试在我的Windows服务下使用它时,它不起作用。套接字错误(仅在将其用于Windows服务时)

公共抽象类SocketClient { 公共静态只读的ILog日志= LogManager.GetLogger(typeof运算(SocketClient));

private System.Net.Sockets.Socket fSocket; 
private bool LocalsocketClientIsShutingDown; 
private byte[] readbuf; 
private byte[] sendbuf; 
private string currentmessage = ""; 

public event EventHandler ConnectionDone; 
public event EventHandler ConnectionFailed; 
public event EventHandler MessageReceivingFailed; 
public event EventHandler MessageSendingFailed; 

public SocketClient() 
{ 
    log4net.Config.XmlConfigurator.Configure(); 
    readbuf = new byte[16384]; 
    this.ConnectionDone += new EventHandler(OnSocketConnectionDone); 
    this.ConnectionFailed += new EventHandler(OnSocketConnectionFailed); 
    this.MessageSendingFailed += new EventHandler(OnMessageSendingFailed); 
    this.MessageReceivingFailed += new EventHandler(OnMessageReceivingFailed); 
} 

public bool isConnected() 
{ 
    if (fSocket == null) 
     return false; 
    return fSocket.Connected; 
} 

protected abstract void OnSocketConnectionDone(object sender, EventArgs e); 
protected abstract void OnSocketConnectionFailed(object sender, EventArgs e); 
protected abstract void OnMessageSendingFailed(object sender, EventArgs e); 
protected abstract void OnMessageReceivingFailed(object sender, EventArgs e); 

protected void ConnectToServer(string ServerName, int Port) 
{ 
    try 
    { 
     log.Debug("SocketClient.ConnectToServer():" + ServerName); 
     if (this.fSocket == null || !this.fSocket.Connected) 
     { 
      this.fSocket = new System.Net.Sockets.Socket(AddressFamily.InterNetwork, SocketType.Stream 
       , ProtocolType.Tcp); 

      IPAddress[] ipadress; 
      log.Debug("ConnectToServer()1"); 
      IPHostEntry he = Dns.GetHostEntry(ServerName); //Dns.Resolve(ServerName); 
      log.Debug("ConnectToServer()2" + he.HostName); 
      ipadress = he.AddressList; 
      //he.AddressList = he.AddressList.ToList().Where(ip => ip.AddressFamily == AddressFamily.InterNetwork).ToArray(); 
      IPEndPoint remoteEP = new IPEndPoint(ipadress[0], Port); 
      if (ServerName=="localhost") 
      { 
       IPHostEntry ipHostInfo = /*Dns.Resolve*/Dns.GetHostEntry(Dns.GetHostName()); //Dns.Resolve(Dns.GetHostName()); 
       //dont take IPv6 IPs 
       //ipHostInfo.AddressList = ipHostInfo.AddressList.ToList().Where(ip => ip.AddressFamily == AddressFamily.InterNetwork).ToArray(); 
       IPAddress ipAddress = ipHostInfo.AddressList[0]; 
       remoteEP = new IPEndPoint(ipAddress, Port); 
      } 
      log.Debug("ConnectToServer()3: start BeginConnect()"); 
      this.fSocket.BeginConnect(remoteEP, new AsyncCallback(ConnectCallback) 
       , this.fSocket); 
      Trace.WriteLine("Connecting to server"); 
     } 
     else 
     { 
      Trace.WriteLine("Already connected to a Server"); 
     } 
    } 
    catch (Exception ex) 
    { 
     Trace.WriteLine("Error connecting to server" + ex.ToString()); 
     OnConnectionFailed(); 
    } 
} 

private void ConnectCallback(IAsyncResult asyncResult) 
{ 
    string[] obj; 
    try 
    { 
     log.Debug("end BeginConnect with ConnectCallback()"); 
     System.Net.Sockets.Socket socket = (System.Net.Sockets.Socket)asyncResult.AsyncState; 
     this.fSocket = socket; 
     socket.EndConnect(asyncResult); 

     this.LocalsocketClientIsShutingDown = false; 

     this.fSocket.BeginReceive(this.readbuf, 0, this.readbuf.Length, SocketFlags.None 
       , new AsyncCallback(ReceiveCallback), this.fSocket); 

     OnConnectionDone(); 

    } 
    catch (SocketException ex) 
    { 
     Trace.WriteLine("Connection Failed: " + ex.Message); 
     OnConnectionFailed(); 
    } 
} 

private void OnConnectionDone() 
{ 
    log.Debug("OnConnectionDone"); 
    if (ConnectionDone != null) 
    { 
     ConnectionDone(this, new EventArgs()); 
    } 
} 
private void OnConnectionFailed() 
{ 
    log.Debug("OnConnectionFailed"); 
    if (ConnectionFailed != null) 
     ConnectionFailed(this, new EventArgs()); 
} 

public void SendMessage(string message) 
{ 
    log.Debug(">>> Sending Message: " + message); 
    if (this.fSocket != null && this.fSocket.Connected) 
    { 
     log.Debug(">>> Sending Message: Begin send 1:" + message); 
     //Turn string into byte for network transfer 
     this.sendbuf = Encoding.ASCII.GetBytes(message); 
     log.Debug(">>> Sending Message: Begin send 2:" + message); 

     this.fSocket.BeginSend(this.sendbuf, 0, this.sendbuf.Length, SocketFlags.None, new AsyncCallback(SendCallback) 
      , this.fSocket); 
    } 
    else 
    { 
     log.Debug("Cant Send Message: " + message + " _ Not connected to socket"); 
     Trace.WriteLine("Not connected to Server"); 
    } 
} 

private void SendCallback(IAsyncResult asyncResult) 
{ 
    try 
    { 
     //On récupere le socket sur lequel on a envoyé les données 
     System.Net.Sockets.Socket socket = (System.Net.Sockets.Socket)asyncResult.AsyncState; 
     //on met fin à l'envois de données 
     int senda = socket.ReceiveBufferSize; 
     int send = socket.EndSend(asyncResult); 

     Trace.WriteLine(">>> Message Sent: " + send + " bytes"); 
     log.Debug(">>> Message Sent: " + send + " bytes"); 
    } 
    catch (SocketException ex) 
    { 
     log.Debug("!!! Message NOT Sent: " + ex.Message); 
     Trace.WriteLine("!!! Message NOT Sent: " + ex.Message); 
     OnMessageSendingFailed(); 
    } 
} 
private void OnMessageSendingFailed() 
{ 
    log.Debug("OnMessageSendingFailed"); 
    if (MessageSendingFailed != null) 
     MessageSendingFailed(this, new EventArgs()); 
} 

public void ReceiveMessage() 
{ 
    try 
    { 
     log.Debug(">>> ReceiveMessage"); 
     if (this.fSocket != null && this.fSocket.Connected) 
      this.fSocket.BeginReceive(this.readbuf, 0, this.readbuf.Length, SocketFlags.None 
       , new AsyncCallback(ReceiveCallback), this.fSocket); 
     else 
     { 
      log.Debug("Not Connected to Server"); 

     } 
    } 
    catch (Exception e) 
    { 
     Console.WriteLine(e.ToString()); 
     OnMessageReceivingFailed(); 
    } 
} 
private void OnMessageReceivingFailed() 
{ 
    log.Debug("OnMessageReceivingFailed"); 
    if (MessageReceivingFailed != null) 
     MessageReceivingFailed(this, new EventArgs()); 
} 

private void ReceiveCallback(IAsyncResult asyncResult) 
{ 
    string[] obj; 

    log.Debug("ReceiveCallback"); 
    try 
    { 
     System.Net.Sockets.Socket socket = (System.Net.Sockets.Socket)asyncResult.AsyncState; 
     log.Debug("ReceiveCallback 2" + socket.ToString()); 

     int read = socket.EndReceive(asyncResult); 

     if (read > 0) 
     { 
      currentmessage += Encoding.ASCII.GetString(this.readbuf, 0, read); 
      log.Debug("ReceiveCallback 3" + currentmessage); 
      char _charEOL = '\n'; 
      if (currentmessage[currentmessage.Length - 1] != _charEOL) 
      { 
       this.fSocket.BeginReceive(this.readbuf, 0, this.readbuf.Length, SocketFlags.None 
        , new AsyncCallback(ReceiveCallback), this.fSocket); 
       return; 
      } 
      readPacket(currentmessage.ToString()); 
      obj = new string[] { "\n\n Server says :" + currentmessage }; 
      currentmessage = ""; 
      Buffer.SetByte(this.readbuf, 0, 0); 
      this.fSocket.BeginReceive(this.readbuf, 0, this.readbuf.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), this.fSocket); 
     } 
     if (read == 0 && !this.LocalsocketClientIsShutingDown) 
     { 
      this.fSocket.Close(); 
      obj = new string[] { "Close Remote Socket" }; 
      log.Debug("ReceiveCallback:Exception1-" + obj); 
     } 
    } 
    catch (SocketException ex) 
    { 
     obj = new string[1] { ex.Message }; 
     log.Debug("ReceiveCallback:Exception2-" + ex.Message); 
    } 
} 

public void readPacket(string aMessage) 
{ 
    log.Debug("readPacket:"+aMessage); 
    try 
    { 

     string _formattedMsg = aMessage.Replace("\n", ""); 
     string[] _tabAllMessages = _formattedMsg.Split(new char[] { '}' }, StringSplitOptions.RemoveEmptyEntries); 
     for (int i = 0; i <= _tabAllMessages.Length - 1; i++) 
     { 
      _tabAllMessages[i] = _tabAllMessages[i] + "}"; 
      //Trace.WriteLine("<<< Message Received: " + aMessage); 
      readSingleMessage(_tabAllMessages[i]); 
     } 
    } 
    finally 
    { 
    } 
} 

public abstract void readSingleMessage(string aMessage);//TO REDEFINE 

public void Close() 
{ 
    log.Debug("SocketClient:Close"); 
    try 
    { 
     if (this.fSocket != null && this.fSocket.Connected) 
     { 
      this.LocalsocketClientIsShutingDown = true; 
      //On ferme le socket 
      this.fSocket.Shutdown(SocketShutdown.Both); 
      System.Threading.Thread.Sleep(500); 

      //On détruit le socket 
      this.fSocket.Close(); 

      Trace.WriteLine("Disconnected"); 
     } 
    } 
    finally 
    { 
    } 
} 

这个问题似乎都来自于该线ConnectCallBack():

this.fSocket.BeginReceive(this.readbuf,0,this.readbuf.Length,SocketFlags.None ,新的AsyncCallback( ReceiveCallback),this.fSocket);

我在客户端应用程序中没有任何问题。 但是,当我在Windows服务中使用套接字时,似乎如果我保留该行,稍后会收到套接字错误。 如果我不保留该行,那么客户端和Windows服务将无法侦听一些消息来读取。

我在使用我的Windows应用程序几个月后失去了一点,在尝试将它变成Windows服务之前从未遇到过问题。

谢谢!

编辑:几个日志:

DEBUG2014-10-02 00:01:27 – Start Session 
DEBUG2014-10-02 00:01:27 – Windows Service: Start Login 
DEBUG2014-10-02 00:01:27 – ImgSocketClient:ConnectToServerAndSendPassword():xxxxxxxxx.com_23459 
DEBUG2014-10-02 00:01:27 – SocketClient.ConnectToServer():xxxxxxxxx.com 
DEBUG2014-10-02 00:01:27 – ConnectToServer()3: start BeginConnect() 
DEBUG2014-10-02 00:01:27 – end BeginConnect with ConnectCallback() 
DEBUG2014-10-02 00:01:27 – OnConnectionDone 
DEBUG2014-10-02 00:01:28 – >>> Socket Connected - Sending Password 
DEBUG2014-10-02 00:01:29 – >>> Sending Message: PASSWORD:xxx 
DEBUG2014-10-02 00:01:29 – >>> Message Sent: 25 bytes 
DEBUG2014-10-02 00:01:29 – ReceiveCallback 
DEBUG2014-10-02 00:01:29 – **ReceiveCallback:Exception1-System.String[]** 
DEBUG2014-10-02 00:01:29 – >>> Password Sent 
DEBUG2014-10-02 00:01:29 – >>> Send Message to suscribe to updates 
DEBUG2014-10-02 00:01:29 – >>> Sending Message: REQUEST:aaaaa 
DEBUG2014-10-02 00:01:29 – Cant Send Message: REQUEST:aaaaa_ Not connected to socket 
+0

是一个SocketException trown?在这种情况下,请与我们分享SocketException.ErrorCode属性。 – Sjips 2014-10-01 21:48:59

+0

也许这是一个权利问题。点击窗口'开始'并在'开始程序...'文本字段中输入'services.msc'。服务视图打开。找到您的服务,右键单击它并选择“属性”。在“登录”选项卡上,尝试指定您自己的帐户而不是本地服务。它做什么(当然重新启动服务之后)?它仍然会抛出错误? – Sjips 2014-10-01 21:53:52

+0

仅在Windows服务下的确切问题是,在我的ReceiveCallback()中,我收到了一个0字节。所以按照我的代码,它会停止连接。但在客户端应用程序下,我从来没有收到0字节。 – user3497492 2014-10-01 21:59:17

回答

0

的问题是在线路:

if (read == 0 && !this.LocalsocketClientIsShutingDown) 
     { 
      this.fSocket.Close(); 
      obj = new string[] { "Close Remote Socket" }; 
      log.Debug("ReceiveCallback:Exception1-" + obj); 
     } 

这是正常的,如果你收到0字节。为什么在这种情况下关闭了插座?关闭套接字后,无法发送消息“REQUEST:aaaaa”...

删除这些行,然后重试。

+0

它是一样的。我以Socket错误结束。 System.Net.Sockets错误:0:[1360] Socket#63062333 :: UpdateStatusAfterSocketError() - ConnectionAborted System.Net.Sockets错误:0:[1360]异常dans套接字#63062333 :: BeginSend - 与我联系的代码放弃了您的浏览器 正如我在评论中所述,问题是我收到了0字节,这在使用我的客户端应用程序下的套接字时从未发生过。 – user3497492 2014-10-02 06:43:51

+0

例如,您是否可以通过Wireshark捕获网络转储,并确定哪一方终止连接?如果FIN或RST包从服务器,你应该看看服务器,为什么它会中止连接。另外,比较两个网络是有用的k转储 - 请求已成功处理并出现错误时。 – Alexander 2014-10-03 06:47:55