Winsock 2 problem

Started by
1 comment, last by ziplux 23 years, 10 months ago
I just read the Winsock 2 tutorial here at gamedev.net, and decided that Winsock was many times less confusing than DirectPlay. So, I created a class for Winsock. All was well until I tested it . Whenever I call send(), my game just crashes and exits. I''m almost positive that I have established a connection and everything. If you want me to post the class (it''s quite large) then say so...but if anyone can help me that would be great. Thanks in advance. Visit our web site: Asylum Entertainment
My Geekcode: "GCS d s: a14 C++$ P+(++) L+ E-- W+++$ K- w++(+++) O---- M-- Y-- PGP- t XR- tv+ b++ DI+(+++) D- G e* h!"Decode my geekcode!Geekcode.com
Visit our web site:Asylum Entertainment
Advertisement
One more thing, I am using async sockets hooked to windows messages using the WASAsyncSelect() function.

Visit our web site:
Asylum Entertainment
My Geekcode: "GCS d s: a14 C++$ P+(++) L+ E-- W+++$ K- w++(+++) O---- M-- Y-- PGP- t XR- tv+ b++ DI+(+++) D- G e* h!"Decode my geekcode!Geekcode.com
Visit our web site:Asylum Entertainment
Ok, I''ll post the code, that might help.
// Here are all the classes I use:class CPoint	{	public:		int x;		int y;	};class CBaseTyp	{	public:		DWORD dwSize;      // size of class		signed char m_type;   // message type		signed char m_dest;   // message destination (set to -1 for everyone, -2 for server)		signed char m_from;   // message from who 	};class CTicTacToePacket : public CBaseTyp	{	public:		CPoint cursorpos;  // cursr position		signed char board[3][3]; // board state	};class CTicTacToeMessage : public CBaseTyp	{	public:		int command; // command		int param;   // paramater	};class CAcceptResponse : public CBaseTyp	{	public:		char name[80];	};class CAccept : public CBaseTyp	{	public:		int playerid;	};class CServer	{	public:		WORD port;		BYTE maxplayers;		int msg_id;		HWND hwnd;		long flags;	};class CConnect	{	public:		char address[15];		WORD port;		int msg_id;		HWND hwnd;		long flags;	};class CPlayer	{	public:		char name[40];		int playerid;	};class CWinsock	{	public:		int InitWS(int version);   // init winsock and request version		void CleanupWS();		int Connect(CConnect info);  // connect to server		int StartServer(CServer info);   // start server		void Close();        // close conneciton or stop server		int ClientSend(char *data);   // send data from client (goes to server)		void ServerProcess(char *data);  // send data to client number from server		void Release();            // release WS		int Accept(HWND hwnd, int msg_id, int flags);    // accept incoming request		char* Read();  // read next message		void ConnectionReady();  // set connection var to ready		void SetName(char* name, int playerid);  // set the name of a certain player		void SetLocal(char *name, int playerid)			{			local.playerid = playerid;   // set id and name of local player			sprintf(local.name, name);			}		bool GetType()			{			return type;			}		int GetLocalID()			{			return local.playerid;			}		bool Connected()			{			return connected;			}	private:		void HandleSysMessage(CTicTacToeMessage message);		CPlayer local;		CPlayer *all;  // only valid in a server instance		int maxplayers;		int numplayers;		SOCKET *sockets;	// Socket array (one for each player)		sockaddr_in attrib;	// attributes		WSADATA ver;  // winsock version		bool type;   // client/server		bool connected;	};int CWinsock :: InitWS(int version)	{	sockets = NULL;	connected = false;	int error = WSAStartup (version, &ver);  // Fill in ver	if (error)		{	// there was an error, no winsock			return FAIL;		}	if (ver.wVersion != version)		{	// wrong WinSock version!			WSACleanup ();	// unload ws2_32.dll			return FAIL;		}	return SUCCESS;	}int CWinsock :: Connect(CConnect info)	{	fprintf(file, "Entering connect...\n");	sockets = new SOCKET;  // allocate memory for socket	*sockets = NULL;	// init socket	type = WST_CLIENT;    // type of instance is client	*sockets = socket (AF_INET, SOCK_STREAM, 0);	// Create socket	WSAAsyncSelect (*sockets, info.hwnd, info.msg_id, info.flags); // set async mode	sockaddr_in target;	target.sin_family = AF_INET; // address family Internet	target.sin_port = htons (info.port) ; // set server''s port number	target.sin_addr.s_addr = inet_addr (info.address); // set server''s IP	if (connect(*sockets, (LPSOCKADDR)&target, sizeof(target)) == SOCKET_ERROR)		{	// an error connecting has occurred!		if(WSAGetLastError() == WSAEWOULDBLOCK) // not ready, retry			{			do				{  // keep trying until connection is established				fprintf(file, "Retry connect...\n");				connect(*sockets, (LPSOCKADDR)&target, sizeof(target));				} while(WSAGetLastError() == WSAEWOULDBLOCK);			}		else			{			fprintf(file, "Connect fail...\n");			WSACleanup ();			return FAIL;			}		}	return SUCCESS;	}void CWinsock :: Close()	{	if(type == WST_CLIENT)		shutdown (*sockets, SD_SEND);	// socket cannot send anymore	else		for (int i = 0; i < maxplayers; i++)   // shutdown all scokets			shutdown(sockets, SD_SEND);	closesocket (*sockets);	// close	if(type == WST_SERVER)		delete []sockets; // free mem	else		delete sockets;	}int CWinsock :: StartServer(CServer info)	{	sockaddr_in server; // info for socket creation and connection	numplayers = 0;	maxplayers = info.maxplayers;   // fill in max players and type of instance	type = WST_SERVER;	sockets = new SOCKET[info.maxplayers+1];  // alloc memory for sockets	all = new CPlayer[info.maxplayers+1];  // alloc memory for player info	sprintf(local.name, "SERVER");         // fill in local player class	local.playerid = 0;	sprintf(all[0].name, local.name);	all[0].playerid = 0;	for(int i = 0; i < maxplayers; i++)    // init sockets		sockets = NULL;<br><br>	sockets[0] = socket (AF_INET, SOCK_STREAM, 0);	// Create socket for server<br><br>	WSAAsyncSelect (sockets[0], info.hwnd, info.msg_id, info.flags); // set async mode<br><br>	server.sin_family = AF_INET; // address family Internet<br>	server.sin_port = htons (info.port) ; // set server''s port number<br>	server.sin_addr.s_addr = htonl(INADDR_ANY); // set server''s IP<br><br>	if (bind(sockets[0], (LPSOCKADDR)&server, sizeof(server)) == SOCKET_ERROR)<br>		{	// an error binding has occurred!<br>			WSACleanup ();<br>			return FAIL;<br>		}<br><br>	if (listen(sockets[0],info.maxplayers)==SOCKET_ERROR)<br>		{	// error!  unable to listen<br>			WSACleanup ();<br>			return FAIL;<br>		}<br>	return SUCCESS;<br>	}<br><br>int  CWinsock :: ClientSend(char *data)<br>	{<br>	fprintf(file, "Attempting to send…(Connected is %d)\n", (int)connected);<br>	if(*sockets != NULL && connected)  // don''t send to an unconnected socket and make sure we are connected<br>		{<br>		if(send(*sockets, data, sizeof(data), 0) == SOCKET_ERROR)  // send directly to server<br>			return FAIL;<br>		else<br>			return SUCCESS;<br>		}<br>	return FAIL;<br>	}<br><br>void CWinsock :: ServerProcess(char *data)<br>	{<br>	CBaseTyp temp;<br><br>	temp = *((CBaseTyp*)data); // cast to CBaseTyp to get address<br><br>	if(temp.m_dest == -1)  // send to all<br>		{<br>		for(int i = 1; i < numplayers+1; i++)<br>			{<br>			if(sockets != NULL)  // don''t send to an unconnected socket<br>				send(sockets, data, sizeof(data), 0);  // send data<br>			}<br>		}<br>	else if(temp.m_dest == -2)  // server command<br>		{<br>		switch(temp.m_type)<br>			{<br>			case SYS_MSG:<br>				{<br>				HandleSysMessage(*((CTicTacToeMessage*)data)); // pass data to sysmessage function<br>				} break;<br>			case TYP_TTTACCEPT:<br>				{<br>				CAcceptResponse msg;      // is a response to accepted<br>				msg = *((CAcceptResponse*)data);<br>				SetName(msg.name, msg.m_from);  // set name field with data from accept response<br>				} break;<br>			}<br>		}<br>	else // send to one person<br>		{<br>		if(sockets[temp.m_dest] != NULL)   // don''t send to an unconnected socket<br>			send(sockets[temp.m_dest], data, sizeof(data), 0); // dispatch message to specified user<br>		}<br>	}<br><br>void CWinsock :: HandleSysMessage(CTicTacToeMessage message)<br>	{<br>	switch(message.command)<br>		{<br>		case CMD_CLOSE:   // we''ve been told to shut down<br>			{<br>			Close();<br>			} break;<br>		}<br>	}<br><br>int CWinsock :: Accept(HWND hwnd, int msg_id, int flags)<br>	{<br>	fprintf(file, "Entering accept…\n");<br>	numplayers++;<br>	sockets[numplayers] = accept(sockets[0], NULL, NULL);  // set the next available socket to the incoming one<br>	<br>	fprintf(file, "%d\n", (int)sockets[numplayers]);<br>	if(sockets[numplayers] != WSAEWOULDBLOCK)<br>		{<br>		if(WSAAsyncSelect (sockets[numplayers], hwnd, msg_id, flags) != SOCKET_ERROR) // set async mode<br>			{<br>			fprintf(file, "Exiting accept…\n");<br>			all[numplayers].playerid = numplayers;  // set id, name will be set later<br>			return SUCCESS;<br>			}<br>		else<br>			{<br>			numplayers–;   // clean up<br>			return FAIL;<br>			}<br>		}<br>	else<br>		{<br>		numplayers–;<br>		return FAIL;<br>		}<br>	}<br><br>char *CWinsock :: Read()<br>	{<br>	CBaseTyp generic;<br>	char *data;<br>	if(type == WST_CLIENT) // client<br>		{<br>		recv(*sockets, (char*)&generic, sizeof(generic), MSG_PEEK);  // peek to get type and size<br>		data = (char*)malloc(generic.dwSize);             // allocate memory<br>		recv(*sockets, data, sizeof(data), 0);       // get data<br>		}<br>	else<br>		{<br>		recv(sockets[0], (char*)&generic, sizeof(generic), MSG_PEEK);  // peek to get type and size<br>		data = (char*)malloc(generic.dwSize);             // allocate memory<br>		recv(sockets[0], data, sizeof(data), 0);       // get data<br>		}<br>	// WARNING!  Must free() the pointer returned by this func after you finish with it<br>	return data;<br>	}<br><br>void CWinsock :: ConnectionReady()<br>	{<br>	connected = true;<br>	}<br><br>void CWinsock :: SetName(char *name, int playerid)<br>	{<br>	sprintf(all[playerid].name, name);  // copy specified name into name field<br>	}<br><br>void CWinsock :: CleanupWS()<br>	{<br>	WSACleanup();<br>	}<br><br>// the messages in WndProc:<br>	case WM_SOCKET_CLIENT:<br>		{<br>		if (WSAGETSELECTERROR(lparam))<br>			{<br>				// error occurred<br>				WSACleanup ();<br>				return 0;<br>			}<br><br>		switch (WSAGETSELECTEVENT(lparam))<br>			{<br>			case FD_READ:	// data has been received<br>				{<br>				CBaseTyp temp;<br>				CAccept accept;<br>				CAcceptResponse cmd;<br>				char *data;<br><br>				data = winsock.Read();    // read data into temporary var<br>				temp = *((CBaseTyp*)data);   // cast to get type<br>				<br>				switch (temp.m_type)  // test type<br>					{<br>					case TYP_TTTPACKET:<br>						{<br>						packet = *((CTicTacToePacket*)data);  // store current data snapshot into global var<br>						} break;<br>					case TYP_TTTACCEPT:<br>						{<br>						accept = *((CAccept*)data);  // here''s our userid<br>						cmd.dwSize = sizeof(cmd);   // fill in size, important<br>						cmd.m_dest = -2;     // server message<br>						cmd.m_from = accept.playerid;  // from us<br>						cmd.m_type = SYS_ARES;     // type is accept response<br>						sprintf(cmd.name, "Test");  // name of player<br>						winsock.SetLocal(cmd.name, accept.playerid);  // set local data<br>						winsock.ClientSend((char*)&cmd);  // send data to server<br>						} break;<br>					}<br>				free(data);<br>				} break;<br>			case FD_CONNECT:	// connection has been accepted<br>				{<br>				winsock.ConnectionReady();<br>				fprintf(file, "——–\nServer connected…\n");<br>				fprintf(file, "%d\n———-\n", (int)winsock.Connected());<br>				} break;<br><br>			}<br>		} break;<br><br>	case WM_SOCKET_SERVER:<br>		{<br>		if (WSAGETSELECTERROR(lparam))<br>			{<br>				// error occurred<br>				WSACleanup ();<br>				return 0;<br>			}<br><br>		switch (WSAGETSELECTEVENT(lparam))<br>			{<br>			case FD_ACCEPT:  // incoming connection request<br>				{<br>				// accept new user and hook it to the WM_SOCKET_CLIENT message<br>				winsock_server.Accept(g_hwnd, WM_SOCKET_CLIENT, FD_READ / FD_CONNECT);<br>				} break;<br>			case FD_READ:	// data has been received<br>				{<br>				char *data;<br>				data = winsock_server.Read();    // read data into temporary var<br>				winsock_server.ServerProcess(data);  // allow server to process data<br>				free(data);   // dealloc memory for data<br>				} break;<br>			case FD_CONNECT:	// connection has been accepted<br>				{<br>				winsock_server.ConnectionReady();<br>				} break;<br>			}<br>		} break;<br><br>// I call this to test it:<br>	CServer info;<br>	CConnect connect;<br>	winsock_server.InitWS(0x202);<br>	info.flags = FD_ACCEPT / FD_READ / FD_CONNECT;<br>	info.hwnd = g_hwnd;<br>	info.maxplayers = 3;<br>	info.msg_id = WM_SOCKET_SERVER;<br>	info.port = 5001;<br>	fprintf(file, "%d\n", winsock_server.StartServer(info));<br><br>	sprintf(connect.address, "127.0.0.1");<br>	connect.flags = FD_READ / FD_CONNECT;<br>	connect.hwnd = g_hwnd;<br>	connect.msg_id = WM_SOCKET_CLIENT;<br>	connect.port = 5001;<br><br>	CTicTacToePacket test;<br><br>	test.dwSize = sizeof(test);<br>	test.m_dest = -1;<br>	test.m_from = winsock.GetLocalID();<br>	test.m_type = TYP_TTTPACKET;<br>	test.cursorpos.x = 105;<br><br>	fprintf(file, "%d\n", winsock.Connect(connect));<br>	winsock.ClientSend((char*)&test);<br> </pre> <br><br>  </i>   <br><br>Visit our web site:<br><a href="http://asylumentertainment.cjb.net">Asylum Entertainment</a>
My Geekcode: "GCS d s: a14 C++$ P+(++) L+ E-- W+++$ K- w++(+++) O---- M-- Y-- PGP- t XR- tv+ b++ DI+(+++) D- G e* h!"Decode my geekcode!Geekcode.com
Visit our web site:Asylum Entertainment

This topic is closed to new replies.

Advertisement