Jump to content

  • Log In with Google      Sign In   
  • Create Account

Winsock 2 problem


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
2 replies to this topic

#1 ziplux   Members   -  Reputation: 122

Like
Likes
Like

Posted 23 June 2000 - 04:20 PM

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

Sponsor:

#2 ziplux   Members   -  Reputation: 122

Like
Likes
Like

Posted 24 June 2000 - 04:38 AM

One more thing, I am using async sockets hooked to windows messages using the WASAsyncSelect() function.

Visit our web site:
Asylum Entertainment

#3 ziplux   Members   -  Reputation: 122

Like
Likes
Like

Posted 24 June 2000 - 10:37 AM

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[i] = NULL;

sockets[0] = socket (AF_INET, SOCK_STREAM, 0); // Create socket for server

WSAAsyncSelect (sockets[0], info.hwnd, info.msg_id, info.flags); // set async mode

server.sin_family = AF_INET; // address family Internet
server.sin_port = htons (info.port) ; // set server''s port number
server.sin_addr.s_addr = htonl(INADDR_ANY); // set server''s IP

if (bind(sockets[0], (LPSOCKADDR)&server, sizeof(server)) == SOCKET_ERROR)
{ // an error binding has occurred!
WSACleanup ();
return FAIL;
}

if (listen(sockets[0],info.maxplayers)==SOCKET_ERROR)
{ // error! unable to listen
WSACleanup ();
return FAIL;
}
return SUCCESS;
}

int CWinsock :: ClientSend(char *data)
{
fprintf(file, "Attempting to send...(Connected is %d)\n", (int)connected);
if(*sockets != NULL && connected) // don''t send to an unconnected socket and make sure we are connected
{
if(send(*sockets, data, sizeof(data), 0) == SOCKET_ERROR) // send directly to server
return FAIL;
else
return SUCCESS;
}
return FAIL;
}

void CWinsock :: ServerProcess(char *data)
{
CBaseTyp temp;

temp = *((CBaseTyp*)data); // cast to CBaseTyp to get address

if(temp.m_dest == -1) // send to all
{
for(int i = 1; i < numplayers+1; i++)
{
if(sockets[i] != NULL) // don''t send to an unconnected socket
send(sockets[i], data, sizeof(data), 0); // send data
}
}
else if(temp.m_dest == -2) // server command
{
switch(temp.m_type)
{
case SYS_MSG:
{
HandleSysMessage(*((CTicTacToeMessage*)data)); // pass data to sysmessage function
} break;
case TYP_TTTACCEPT:
{
CAcceptResponse msg; // is a response to accepted
msg = *((CAcceptResponse*)data);
SetName(msg.name, msg.m_from); // set name field with data from accept response
} break;
}
}
else // send to one person
{
if(sockets[temp.m_dest] != NULL) // don''t send to an unconnected socket
send(sockets[temp.m_dest], data, sizeof(data), 0); // dispatch message to specified user
}
}

void CWinsock :: HandleSysMessage(CTicTacToeMessage message)
{
switch(message.command)
{
case CMD_CLOSE: // we''ve been told to shut down
{
Close();
} break;
}
}

int CWinsock :: Accept(HWND hwnd, int msg_id, int flags)
{
fprintf(file, "Entering accept...\n");
numplayers++;
sockets[numplayers] = accept(sockets[0], NULL, NULL); // set the next available socket to the incoming one

fprintf(file, "%d\n", (int)sockets[numplayers]);
if(sockets[numplayers] != WSAEWOULDBLOCK)
{
if(WSAAsyncSelect (sockets[numplayers], hwnd, msg_id, flags) != SOCKET_ERROR) // set async mode
{
fprintf(file, "Exiting accept...\n");
all[numplayers].playerid = numplayers; // set id, name will be set later
return SUCCESS;
}
else
{
numplayers--; // clean up
return FAIL;
}
}
else
{
numplayers--;
return FAIL;
}
}

char *CWinsock :: Read()
{
CBaseTyp generic;
char *data;
if(type == WST_CLIENT) // client
{
recv(*sockets, (char*)&generic, sizeof(generic), MSG_PEEK); // peek to get type and size
data = (char*)malloc(generic.dwSize); // allocate memory
recv(*sockets, data, sizeof(data), 0); // get data
}
else
{
recv(sockets[0], (char*)&generic, sizeof(generic), MSG_PEEK); // peek to get type and size
data = (char*)malloc(generic.dwSize); // allocate memory
recv(sockets[0], data, sizeof(data), 0); // get data
}
// WARNING! Must free() the pointer returned by this func after you finish with it
return data;
}

void CWinsock :: ConnectionReady()
{
connected = true;
}

void CWinsock :: SetName(char *name, int playerid)
{
sprintf(all[playerid].name, name); // copy specified name into name field
}

void CWinsock :: CleanupWS()
{
WSACleanup();
}

// the messages in WndProc:
case WM_SOCKET_CLIENT:
{
if (WSAGETSELECTERROR(lparam))
{
// error occurred
WSACleanup ();
return 0;
}

switch (WSAGETSELECTEVENT(lparam))
{
case FD_READ: // data has been received
{
CBaseTyp temp;
CAccept accept;
CAcceptResponse cmd;
char *data;

data = winsock.Read(); // read data into temporary var
temp = *((CBaseTyp*)data); // cast to get type

switch (temp.m_type) // test type
{
case TYP_TTTPACKET:
{
packet = *((CTicTacToePacket*)data); // store current data snapshot into global var
} break;
case TYP_TTTACCEPT:
{
accept = *((CAccept*)data); // here''s our userid
cmd.dwSize = sizeof(cmd); // fill in size, important
cmd.m_dest = -2; // server message
cmd.m_from = accept.playerid; // from us
cmd.m_type = SYS_ARES; // type is accept response
sprintf(cmd.name, "Test"); // name of player
winsock.SetLocal(cmd.name, accept.playerid); // set local data
winsock.ClientSend((char*)&cmd); // send data to server
} break;
}
free(data);
} break;
case FD_CONNECT: // connection has been accepted
{
winsock.ConnectionReady();
fprintf(file, "--------\nServer connected...\n");
fprintf(file, "%d\n----------\n", (int)winsock.Connected());
} break;

}
} break;

case WM_SOCKET_SERVER:
{
if (WSAGETSELECTERROR(lparam))
{
// error occurred
WSACleanup ();
return 0;
}

switch (WSAGETSELECTEVENT(lparam))
{
case FD_ACCEPT: // incoming connection request
{
// accept new user and hook it to the WM_SOCKET_CLIENT message
winsock_server.Accept(g_hwnd, WM_SOCKET_CLIENT, FD_READ / FD_CONNECT);
} break;
case FD_READ: // data has been received
{
char *data;
data = winsock_server.Read(); // read data into temporary var
winsock_server.ServerProcess(data); // allow server to process data
free(data); // dealloc memory for data
} break;
case FD_CONNECT: // connection has been accepted
{
winsock_server.ConnectionReady();
} break;
}
} break;

// I call this to test it:
CServer info;
CConnect connect;
winsock_server.InitWS(0x202);
info.flags = FD_ACCEPT / FD_READ / FD_CONNECT;
info.hwnd = g_hwnd;
info.maxplayers = 3;
info.msg_id = WM_SOCKET_SERVER;
info.port = 5001;
fprintf(file, "%d\n", winsock_server.StartServer(info));

sprintf(connect.address, "127.0.0.1");
connect.flags = FD_READ / FD_CONNECT;
connect.hwnd = g_hwnd;
connect.msg_id = WM_SOCKET_CLIENT;
connect.port = 5001;

CTicTacToePacket test;

test.dwSize = sizeof(test);
test.m_dest = -1;
test.m_from = winsock.GetLocalID();
test.m_type = TYP_TTTPACKET;
test.cursorpos.x = 105;

fprintf(file, "%d\n", winsock.Connect(connect));
winsock.ClientSend((char*)&test);




Visit our web site:
Asylum Entertainment




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS