Jump to content
  • Advertisement
Sign in to follow this  

Winsock inside a service problem

This topic is 1743 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I got the sample from here: click

The code:





char* WebPost(char Website[], char Webpage[], char Request[], int RetLen) 
{
	// Sends an HTTP Post request with POST Data...
	// Absolutly NOT error checking, which needs fixing!

	SOCKET WebSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

	struct hostent *WebHost;
	WebHost = gethostbyname(Website);
	if (WebHost == NULL) 
	{
		if (WSAGetLastError() == WSANOTINITIALISED)
			OutputDebugString(L"Error Not Connected! line 70");
		else
			OutputDebugString(L"Error: line 72");

		Sleep(1000);
		exit(0);

	}

	SOCKADDR_IN SockAddr;
	SockAddr.sin_port	= htons(80);
	SockAddr.sin_family	= AF_INET;

	SockAddr.sin_addr.s_addr = *((unsigned long*)WebHost->h_addr);
	connect(WebSocket, (SOCKADDR*)(&SockAddr), sizeof(SockAddr));


	char PostRequest[1024];

	sprintf(PostRequest,
		"POST %s HTTP/1.1\r\n"
		"Host: %s\r\n"
		"Content-Length: %hu\r\n"
		"Content-Type: application/x-www-form-urlencoded\r\n"
		"\r\nD=%s\0",
		Webpage, Website,
		strlen(Request)+2, Request
	);

	send(WebSocket, PostRequest, strlen(PostRequest), 0);


	// Get return data 

	char* Data = new char[RetLen];
	recv(WebSocket, Data, 4, 0);

	for (;;) 
	{							// Skip HTTP headers
		Data[0] = Data[1];
		Data[1] = Data[2];
		Data[2] = Data[3];

		recv(WebSocket, &Data[3], 1, 0);

		if (Data[0] == '\r' && Data[1] == '\n'
		&&	Data[2] == '\r' && Data[3] == '\n')
			break;

	}

	int DataLen = recv(WebSocket, Data, RetLen, 0);
	Data[DataLen] = '\0';	// Return the data

	shutdown(WebSocket, 2);
	closesocket(WebSocket);
	return Data;

}







void ServStart() 
{
	WSADATA wsaData; 

	if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0) 
	{
		OutputDebugString(L"error at line 138");
		exit(138);
	}


	if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) 
	{
		OutputDebugString(L"The dll do not support the Winsock versin");
		WSACleanup();
		exit(147);
	}

	// Start listening 
	ListeningSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

	if (ListeningSocket == INVALID_SOCKET) 
	{
		OutputDebugString(L"Error at socket, line 155");
		WSACleanup();
		exit(157);
	}

	ServerAddr.sin_family = AF_INET;
	ServerAddr.sin_port = htons(Port);
	ServerAddr.sin_addr.s_addr = htonl(INADDR_ANY);

	if (bind(ListeningSocket, (SOCKADDR *)&ServerAddr, sizeof(ServerAddr)) == SOCKET_ERROR) 
	{
		OutputDebugString(L"bind failed. Error code: line 166");
		closesocket(ListeningSocket);
		WSACleanup();
		exit(169);
	}

	if (listen(ListeningSocket, 5) == SOCKET_ERROR) 
	{
		OutputDebugString(L"listen: Error listening on socket line 174");
		closesocket(ListeningSocket);
		WSACleanup();
		exit(177);
	}


// Gets your external (public) IP	< Internet
	//MyIP = WebPost("api.externalip.net", "/ip/", "", 16);			// Get my IP
	//char HostName[255];
	//hostent *HostEntry;
	//gethostname(HostName, 255);
	//HostEntry = gethostbyname(HostName);
	//MyIP = inet_ntoa(*(struct in_addr *)*HostEntry->h_addr_list);		


	char ac[80];
	if (gethostname(ac, sizeof(ac)) == SOCKET_ERROR) 
	{
		OutputDebugString(L"Error when getting local host name."); 
		exit(194);
	}

	struct hostent *phe = gethostbyname(ac);
	if (phe == 0) 
	{
		 OutputDebugString(L"Error at line 200"); 
		exit(201);
	}
	
	struct in_addr addr;
	memcpy(&addr, phe->h_addr_list[0], sizeof(struct in_addr)); // use the first ip-address
	
	MyIP = inet_ntoa(addr);

	char SendBuf[32];
	// * is used as a separator, because it's not allowed in the hostname. 
	//So it won't interfere with it. 
	sprintf(SendBuf, "%hhu|%s*%s", cAddIP, MyIP, ac);	// Send the server the IP and host name
	WebPost(WEBSITE, WEBPAGE, SendBuf, 0);

	OutputDebugString(L"listening for connections...\n\n");

}

void ShutDown() 			// Shut down the server (tells the web server I am offline)
{
	char SendBuf[32];		// Remove my IP from the list of online servers...
	char ac[80];
	if (gethostname(ac, sizeof(ac)) == SOCKET_ERROR) 
	{
		printf("Error when getting local host name: ", WSAGetLastError()); 
		exit(226);
	}
	sprintf(SendBuf, "%hhu|%s*%s", cRemIP, MyIP,ac);
	WebPost(WEBSITE, WEBPAGE, SendBuf, 0);

	printf("Successful shutdown\n");
	Sleep(1000);

	WSACleanup();

}








void CSampleService::ServiceWorkerThread(void)
{
	ServStart();
	

	
    // Periodically check if the service is stopping.
	
    while (!m_fStopping)
	{
    

	SOCKADDR_IN SenderInfo;
	SOCKET NewConnection;

	int ByteReceived, nlen;
	char recvbuff[1024];
		// Main program loop
		NewConnection = SOCKET_ERROR;
		if(NewConnection == SOCKET_ERROR) 
		{
		
			NewConnection = accept(ListeningSocket, NULL, NULL);	// this is a blocking function
			OutputDebugString(L"New client got connected, ready to receive and send data...\n\n");
			ByteReceived = recv(NewConnection, recvbuff, sizeof(recvbuff), 0);

			if (ByteReceived > 0) 
			{
				getsockname(ListeningSocket, (SOCKADDR *)&ServerAddr, (int *)sizeof(ServerAddr));

				memset(&SenderInfo, 0, sizeof(SenderInfo));
				nlen = sizeof(SenderInfo);

				getpeername(NewConnection, (SOCKADDR *)&SenderInfo, &nlen);	
			}

		}
		if (shutdown(NewConnection, 2) != 0)
			OutputDebugString(L"Line 355");
		else
			OutputDebugString(L"shutdown is working...\n");

		

	
	}

    // Signal the stopped event.
    SetEvent(m_hStoppedEvent);
}

As you can see,it's the code form a simple server.But,when I try to connect to it,nothing.If I just run it as a console app,it works fine.

What's the problem?

Edited by noatom

Share this post


Link to post
Share on other sites
Advertisement

printf isn't going to work in a service. Have you set breakpoints on all the exit(0) calls/failures?

 

(Also, exit(0) means "everything is ok", same as returning 0 from main(). You should probably exit with a non-zero error code?).

Edited by Paradigm Shifter

Share this post


Link to post
Share on other sites

Neither will work anything GUI related towards the user. Services per default are not supposed to interact with the Desktop.

 

However it's possible to enable interaction manually (in the Service Manager). Not recommended though. Write a log file somewhere or use the Event Manager..

Share this post


Link to post
Share on other sites

So,printfs and exit codes....I'm pretty sure they're not affecting the code,they're just leftovers from the copy-paste.

 

And this is just winsock,it is not intended to react with the desktop.I'm gonna create a log file..

Share this post


Link to post
Share on other sites

I updated the code in the first post.

 

So I changed the printfs to outputdebugstrings and the exit codes to the number of the line in visual studio,I also removed the messageboxes,but all I get in visual studio is:

'CppWindowsService.exe': Loaded 'C:\test2\CppWindowsService.exe', Symbols loaded.
'CppWindowsService.exe': Loaded 'C:\Windows\System32\ntdll.dll', Cannot find or open the PDB file
'CppWindowsService.exe': Loaded 'C:\Windows\System32\kernel32.dll', Cannot find or open the PDB file
'CppWindowsService.exe': Loaded 'C:\Windows\System32\KernelBase.dll', Cannot find or open the PDB file
'CppWindowsService.exe': Loaded 'C:\Windows\System32\advapi32.dll', Cannot find or open the PDB file
'CppWindowsService.exe': Loaded 'C:\Windows\System32\msvcrt.dll', Cannot find or open the PDB file
'CppWindowsService.exe': Loaded 'C:\Windows\System32\sechost.dll', Cannot find or open the PDB file
'CppWindowsService.exe': Loaded 'C:\Windows\System32\rpcrt4.dll', Cannot find or open the PDB file
'CppWindowsService.exe': Loaded 'C:\Windows\System32\msvcr100d.dll', Symbols loaded.
'CppWindowsService.exe': Loaded 'C:\Windows\System32\msvcp100d.dll', Symbols loaded.
'CppWindowsService.exe': Loaded 'C:\Windows\System32\ws2_32.dll', Cannot find or open the PDB file
'CppWindowsService.exe': Loaded 'C:\Windows\System32\nsi.dll', Cannot find or open the PDB file
'CppWindowsService.exe': Loaded 'C:\Windows\System32\mswsock.dll', Cannot find or open the PDB file
'CppWindowsService.exe': Loaded 'C:\Windows\System32\user32.dll', Cannot find or open the PDB file
'CppWindowsService.exe': Loaded 'C:\Windows\System32\gdi32.dll', Cannot find or open the PDB file
'CppWindowsService.exe': Loaded 'C:\Windows\System32\lpk.dll', Cannot find or open the PDB file
'CppWindowsService.exe': Loaded 'C:\Windows\System32\usp10.dll', Cannot find or open the PDB file
'CppWindowsService.exe': Loaded 'C:\Windows\System32\imm32.dll', Cannot find or open the PDB file
'CppWindowsService.exe': Loaded 'C:\Windows\System32\msctf.dll', Cannot find or open the PDB file
'CppWindowsService.exe': Loaded 'C:\Windows\System32\WSHTCPIP.DLL', Cannot find or open the PDB file
'CppWindowsService.exe': Loaded 'C:\Windows\System32\nlaapi.dll', Cannot find or open the PDB file
'CppWindowsService.exe': Loaded 'C:\Windows\System32\NapiNSP.dll', Cannot find or open the PDB file
'CppWindowsService.exe': Loaded 'C:\Windows\System32\pnrpnsp.dll', Cannot find or open the PDB file
'CppWindowsService.exe': Loaded 'C:\Windows\System32\dnsapi.dll', Cannot find or open the PDB file
'CppWindowsService.exe': Loaded 'C:\Windows\System32\winrnr.dll', Cannot find or open the PDB file
'CppWindowsService.exe': Loaded 'C:\Windows\System32\IPHLPAPI.DLL', Cannot find or open the PDB file
'CppWindowsService.exe': Loaded 'C:\Windows\System32\winnsi.dll', Cannot find or open the PDB file
'CppWindowsService.exe': Loaded 'C:\Windows\System32\FWPUCLNT.DLL', Cannot find or open the PDB file
'CppWindowsService.exe': Loaded 'C:\Windows\System32\rasadhlp.dll', Cannot find or open the PDB file
The thread 'Win32 Thread' (0x68c) has exited with code 0 (0x0).

I debugged the service like this: http://msdn.microsoft.com/en-us/library/7a50syb3.aspx

 

Some help?

Edited by noatom

Share this post


Link to post
Share on other sites

I checked with the services in the services manager,it does not stop,however it throws these messages:

The thread 'Win32 Thread' (0x68c) has exited with code 0 (0x0).

 

with different hexadecimal codes like every 2 minutes.

Share this post


Link to post
Share on other sites

That's normal as well... threads get spawned and exit quite a lot.

 

Are you sure OutputDebugString is working? It looks like you don't get any output at all from your program. Output something as soon as your program starts (dunno what the entry point for a service is). You are running the service through the debugger, right? (Presumably, since you see some output).

 

If you do see output, you want to output stuff that succeeds as well and put some output throughout the program so you can see what it is doing.

Share this post


Link to post
Share on other sites

Starting with Vista services run in "session 0", while normal programs run in "session 1". It's not so easy to capture OutputDebugString output with VS now.

 

You could use DebugView (http://technet.microsoft.com/en-us/sysinternals/bb896647.aspx) which has an option to capture global ODS calls (named something like global win32).

 

Or as said, use a log file or the event system ;)

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!