Windows service with Socket won't accept a connection

P

Paul Tulou

Hello,

I have created a Windows service that uses the Socket class to listen
for incoming connections. I have tested my socket code in a normal
windows application for easy debugging and everything worked fine.
When I transfered this code to the service and started it up, the
service runs fine and stops fine, but any messages sent via telnet to
the IP are simply not received. No connection is ever made. Keep in
mind that the only difference (that I have found) between the working
and non-working versions is the type of application (app vs. service).

I am currently running the service in LocalSystem mode, although I have
also tried running it under my user login that has administrative
privileges. Both worked the same. Should there be any restrictions on
Sockets use based on which Account is used for the service?

The only thing I can think is that maybe there are extra setup steps
that I need to go through in order to get sockets to work with my
service. I have included my code below. The BeginAccept method
executes fine but the AcceptCallback method never gets executed until
the OnStop method closes the socket.

Any help with this would be greatly appreciated, I haven't had much
luck finding documentation on this.


namespace VerizonServer
{
public partial class VerizonServer : ServiceBase
{
private string outputPath;
private int port;
private Socket socket;
private TextLog log;

public VerizonServer()
{
InitializeComponent();

if
(!System.Diagnostics.EventLog.SourceExists("VerizonServerService"))

System.Diagnostics.EventLog.CreateEventSource("VerizonServerService",
"VerizonServerLog");

eventLog.Source = "VerizonServerService";
eventLog.Log = "VerizonServerLog";

log = new TextLog(Application.StartupPath + @"\Logs",
"VerizonLog");
}

protected override void OnStart(string[] args)
{
try
{
base.OnStart(args);

outputPath =
ConfigurationSettings.AppSettings.Get("OutputPath");
port =
int.Parse(ConfigurationSettings.AppSettings.Get("Port"));

IPEndPoint localEndPoint = new
IPEndPoint(IPAddress.Any, port);
socket = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
socket.Bind(localEndPoint);
socket.Listen(100);
socket.BeginAccept(new AsyncCallback(AcceptCallback),
socket);

string message = string.Format("Service started
successfully.\r\n\tOutput Path:\t{0}\r\n" +
"\tPort:\t{1}", outputPath, port);
eventLog.WriteEntry(message);
log.LogEvent(message);
}
catch (Exception ex)
{
eventLog.WriteEntry(ex.ToString());
log.LogEvent(ex.ToString());
}
}

protected override void OnStop()
{
socket.Close();
base.OnStop();
eventLog.WriteEntry("Service stopped successfully.");
log.LogEvent("Service stopped successfully.");
}

private void AcceptCallback(IAsyncResult ar)
{
// Code omitted: I process the the data received upon
connection here
}
}
}
 
P

Paul Tulou

After continuing to troubleshoot the problem, I have found that if I
build the setup file and deploy the project to separate machine (our
server), the service runs fine. The account is still LocalSystem. My
development machine that I was previously using is an XP SP2 laptop. I
wouldn't think that this should cause a problem, but maybe it will shed
light on what the problem is?
 
E

EmeraldShield

Paul Tulou said:
Hello,

I have created a Windows service that uses the Socket class to listen
for incoming connections. I have tested my socket code in a normal
windows application for easy debugging and everything worked fine.
When I transfered this code to the service and started it up, the
service runs fine and stops fine, but any messages sent via telnet to
the IP are simply not received. No connection is ever made. Keep in
mind that the only difference (that I have found) between the working
and non-working versions is the type of application (app vs. service).

It looks to me like you are exiting your app. When the service starts you
have to spin off a thread for the app itself. The app appears to just exit.
Look in your process list and I think you will see the app appear and then
go away.
 
P

Paul Tulou

It looks to me like you are exiting your app. When the service starts you
have to spin off a thread for the app itself. The app appears to just exit.
Look in your process list and I think you will see the app appear and then
go away.

First off, thanks for the response! :) The spun-off thread is created
by the Socket.BeginAccept() call. This waits for an incoming
connection and then calls the AcceptCallback function. The callback
function then re-calls BeginAccept() so that it is ready for new
connections. I verified in my process list that the service is still
running and I am able to connect to it from within VS2005, so I'm
pretty sure it is not prematurely exiting. I'll attach the complete
callback method below so that you can see what I'm talking about.

private void AcceptCallback(IAsyncResult ar)
{
byte[] buffer = new byte[1024];
bool receiveLoop = true;
int numberReceived = 0;
StringBuilder sb = new StringBuilder();

try
{
// Get the socket that handles the client request
Socket socket = (Socket)ar.AsyncState;
Socket handler = socket.EndAccept(ar);

log.LogEvent("Connection accepted");

// Restart the accept thread
socket.BeginAccept(new AsyncCallback(AcceptCallback),
socket);

handler.ReceiveTimeout = 10000;
while (receiveLoop)
{
handler.Poll(-1, SelectMode.SelectRead);
numberReceived = handler.Receive(buffer);
for (int i = 0; i < numberReceived; i++)
sb.Append(buffer.ToString("X2"));
if (0 == numberReceived)
receiveLoop = false;
}

handler.Close();

if (sb.Length > 0)
CreateXmlFile(sb.ToString());
}
catch (ObjectDisposedException)
{
return;
}
catch (Exception ex)
{
eventLog.WriteEntry(ex.ToString());
log.LogEvent(ex.ToString());
}
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top