Skip to main content
GameDev.net gamedev.net
🔒 Locked

CAsynchSocket...CSocket, Help!

Started by PhlashStudios Apr 13, 2006 at 11:23 AM 14 replies 1k views
Original Post
PhlashStudios
PhlashStudios
Hi I am using visual c++ .net 2003. I have recently been programming clients and servers in python, which is a total breeze with getting a client to connect to a server and listen for messages taking only a couple easy lines of code. I recently decided to try my hand at doing this in Visual C++, but all of the example code on MSDN seems really complex and way over my head. Does anyone know of any simple examples of clients just to get my feet wet...Nothing too complicated, just a couple of functions to connect and listen to a server?? (Besides something like ACE) Thanks in advance.
<a href="http://eyeredux.com/campaigns/1/redirect">Hello!</a>
PhlashStudios
PhlashStudios
Quote:
Original post by Evil Steve
I'd recommend Beej's Guide to Network Programming. Socket code in C / C++ is a lot more in depth than Python.


Yes I've seen that but im pretty sure it said that those examples were not for windows or visual c++.
<a href="http://eyeredux.com/campaigns/1/redirect">Hello!</a>
Evil Steve
Evil Steve
Quote:
Original post by PhlashStudios
Quote:
Original post by Evil Steve
I'd recommend Beej's Guide to Network Programming. Socket code in C / C++ is a lot more in depth than Python.


Yes I've seen that but im pretty sure it said that those examples were not for windows or visual c++.
It doesn't matter. Visual C++ is the same as C++, and the sockets is all BSD stuff, which works fine on Windows.
PhlashStudios
PhlashStudios
Alright I'll give it whirl...thanks
<a href="http://eyeredux.com/campaigns/1/redirect">Hello!</a>
PhlashStudios
PhlashStudios
I followed the instructions for setting it up on my compiler, and wrote some sample code, but it won't compile here is the code:
#include <winsock.h>int main(){        WSADATA wsaData;   // if this doesn't work    //WSAData wsaData; // then try this instead    if (WSAStartup(MAKEWORD(1, 1), &wsaData) != 0) {        fprintf(stderr, "WSAStartup failed.\n");        exit(1);	int s = socket(AF_INET, SOCK_STREAM, 0);     }}


Here are the errors:

error C3861: 'fprintf': identifier not found, even with argument-dependent lookup

error C2065: 'stderr' : undeclared identifier
any suggestions?
<a href="http://eyeredux.com/campaigns/1/redirect">Hello!</a>
PhlashStudios
PhlashStudios
Sorry ignore the last post here is the new code:
#include <winsock.h>int main(){    WSADATA wsaData;   // if this doesn't work    //WSAData wsaData; // then try this instead	/*    if (WSAStartup(MAKEWORD(1, 1), &wsaData) != 0) {        fprintf(stderr, "WSAStartup failed.\n");        exit(1);	*/    int s = socket(AF_INET, SOCK_STREAM, 0); }

And here are the errors:
error LNK2019: unresolved external symbol _WinMain@16 referenced in function _WinMainCRTStartup

fatal error LNK1120: 1 unresolved externals

warning C4101: 'wsaData' : unreferenced local variable


<a href="http://eyeredux.com/campaigns/1/redirect">Hello!</a>
Evil Steve
Evil Steve
You created a Win32 application, not a console application.
Change:
int main()
to:
int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
Or re-create the project.
The first error is because you haven't included stdio.h.
PhlashStudios
PhlashStudios
I wrote some code to test out a simple server I wrote in python thats running on the same machine:
#include <winsock.h>#include <stdio.h>#include "Resources.h"int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int){	    WSADATA wsaData;   // if this doesn't work    //WSAData wsaData; // then try this instead	    if (WSAStartup(MAKEWORD(1, 1), &wsaData) != 0) {        fprintf(stderr, "WSAStartup failed.\n");        exit(1);		}		struct sockaddr_in dest_addr; //will hold the dest address		int s = socket(AF_INET, SOCK_STREAM, 0);	dest_addr.sin_family = AF_INET; //host byte order	dest_addr.sin_port = htons(PORT); //short, network byte order	dest_addr.sin_addr.s_addr = inet_addr(HOST);	memset(&(dest_addr.sin_zero), '\0', 8); //zero the rest of the struct	int err = connect(s, (struct sockaddr *)&dest_addr, sizeof(struct sockaddr));		if(err = -1)	{		MessageBox(NULL, "Error-Failure to connect!",		"Error C1045",		MB_YESNO | MB_ICONQUESTION);	}}


But my error message box keeps popping up, any idea why?
(the host and port are in a seperate resources file and are localhost and 1337)
Thanks
<a href="http://eyeredux.com/campaigns/1/redirect">Hello!</a>
Evil Steve
Evil Steve
What is the value of PORT and HOST? HOST should be an IP address, e.g. "123.123.123.123", not a hostname like "gamedev.net". If you're using a hostname, you'll need to use gethostbyname() to resolve it to an IP first.

Also, I'd check that socket() doesn't return INVALID_SOCKET.

EDIT: Ah, you edited your post [smile]. If HOST == "localhost", you'll need to resolve it to an IP. Here's what I use:
// Try to resolve it as an IPdest_addr.sin_addr.s_addr = inet_addr(HOST);if(dest_addr.sin_addr.s_addr == INADDR_NONE){   // Failed. Not an IP. Lookup a hostname   hostent* pHost = gethostbyname(HOST);   if(!pHost)   {      // Error, couldn't lookup hostname. Probably doesn't exist   }   dest_addr.sin_addr = *(in_addr*)pHost->h_addr;}
PhlashStudios
PhlashStudios
I changed the code to this: (and ran it again, and the error still popped up)
#include <winsock.h>#include <stdio.h>#include "Resources.h"int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int){	    WSADATA wsaData;   // if this doesn't work    //WSAData wsaData; // then try this instead	    if (WSAStartup(MAKEWORD(1, 1), &wsaData) != 0) {        fprintf(stderr, "WSAStartup failed.\n");        exit(1);		}		struct sockaddr_in dest_addr; //will hold the dest address		int s = socket(AF_INET, SOCK_STREAM, 0);	dest_addr.sin_family = AF_INET; //host byte order	dest_addr.sin_port = htons(PORT); //short, network byte order	dest_addr.sin_addr.s_addr = inet_addr(HOST);	if(dest_addr.sin_addr.s_addr == INADDR_NONE)	{		// Failed. Not an IP. Lookup a hostname		hostent* pHost = gethostbyname(HOST);		if(!pHost)		{			// Error, couldn't lookup hostname. Probably doesn't exist		}		dest_addr.sin_addr = *(in_addr*)pHost->h_addr;	}	memset(&(dest_addr.sin_zero), '\0', 8); //zero the rest of the struct	int err = connect(s, (struct sockaddr *)&dest_addr, sizeof(struct sockaddr));		if(err = -1)	{		MessageBox(NULL, "Error-Failure to connect!",		"Error C1045",		MB_YESNO | MB_ICONQUESTION);	}}


By the way I'm pretty sure that it's not the server thats at fault because I telnetted into it and it worked fine....
<a href="http://eyeredux.com/campaigns/1/redirect">Hello!</a>
PhlashStudios
PhlashStudios
Alright I have the client and server connection working fine now, but when I have the server, send the client something, i get what is sent, but there is aload of junk after it. How do I sort out the junk from the good stuff. And also, when I send something from the client to the server I'm pretty sure i need a /r/n postfix for it to register. But when I try to join for example these two variables:
char username[50] = "PhlashStudios"
char postfix[50] = "/r/n"
send(s, username + postfix, 100, 0)
I get and error that says I can't do that. Any way around this?

[Edited by - PhlashStudios on April 14, 2006 12:12:49 PM]
<a href="http://eyeredux.com/campaigns/1/redirect">Hello!</a>
ApochPiQ
ApochPiQ
That's not how strings work in C or C++, unfortunately. Have a look at std::string - that should be a lot closer to what you're used to from Python.

Oh, and one other thing - I know you probably don't want to hear this at this stage, but please please please don't use MFC CSocket. It sucks terribly. You'll be much better off just using Winsock directly. Even better, use the BSD-sockets compatible layer of Winsock (socket, connect, select, et. al.) and then your sockets knowledge will be portable to other platforms and languages easily.

[edit] Nevermind, I didn't read the thread carefully enough [smile]
PhlashStudios
PhlashStudios
Can I use these strings for the send and recv commands as well as to get info from my dialogs?
<a href="http://eyeredux.com/campaigns/1/redirect">Hello!</a>
ApochPiQ
ApochPiQ
Sadly, it isn't quite that convenient.

A send you can do easily since std::string supports falling back to C-style strings:
send(socket, SomeString.c_str(), SomeString.length(), 0);

However, recv (and, generally, any API that needs to put data into a string) doesn't know what to do with such a string. So you have to do some goofiness like this:

char TemporaryBuffer[1024];recv(socket, TemporaryBuffer, sizeof(TemporaryBuffer), 0);std::string ActualStringBuffer(TemporaryBuffer);// Now you have the data copied into the string and can do stringy stuff to it

PhlashStudios
PhlashStudios
Cool thanks.
<a href="http://eyeredux.com/campaigns/1/redirect">Hello!</a>

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.