我的问题只发生在我尝试在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
是一个SocketException trown?在这种情况下,请与我们分享SocketException.ErrorCode属性。 – Sjips 2014-10-01 21:48:59
也许这是一个权利问题。点击窗口'开始'并在'开始程序...'文本字段中输入'services.msc'。服务视图打开。找到您的服务,右键单击它并选择“属性”。在“登录”选项卡上,尝试指定您自己的帐户而不是本地服务。它做什么(当然重新启动服务之后)?它仍然会抛出错误? – Sjips 2014-10-01 21:53:52
仅在Windows服务下的确切问题是,在我的ReceiveCallback()中,我收到了一个0字节。所以按照我的代码,它会停止连接。但在客户端应用程序下,我从来没有收到0字节。 – user3497492 2014-10-01 21:59:17