Winsock 2 problem
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
Visit our web site:Asylum Entertainment
One more thing, I am using async sockets hooked to windows messages using the WASAsyncSelect() function.
Visit our web site:
Asylum Entertainment
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
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)⌖, 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)⌖, 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
Visit our web site:Asylum Entertainment
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement