Original Post
Alright, I am trying to write a mud. Learning WinSock seemed like a good start.
Well, I am trying to get this tutorial to work but make it better suited to a game engine (made it oo). Problem is it doesn't really explain how to get messages good, and my program dies whenever somone disconnects.
Here is the main body
#include <iostream>
#include <stdlib.h>
#include "mysock.h"
using namespace std;
int main(int argc, char *argv[])
{
Server.setup();
while(Server.isRunning()){
Server.acceptConnection();
Server.getMessages();
if(GetAsyncKeyState(VK_ESCAPE))
Server.shutdown();
}
return 0;
}
Pretty simple.
The header where I wrote everything is kinda big though...
#ifndef MY_SOCKET_WRAPPER
#define MY_SOCKET_WRAPPER 1
#include <winsock.h>
#include <stdio.h>
#include <iostream>
#include <string>
using namespace std;
class cSocketWrapper{
public:
class cClientData{
public:
int state;
SOCKET clientSocket;
sockaddr_in clientAddress;
cClientData(){ state = 0; };
void disconnect();
bool getMessage();
};
int currentClients;
cClientData listeningSocket;
cClientData clients[200];
timeval timeout;
int port;
string serverAddress;
bool setup();
void shutdown();
void acceptConnection();
void getMessages();
bool isRunning(){
return running;
};
cSocketWrapper(int _port=8903, string _serverAddress="127.0.0.1"){
running = false;
port = _port;
serverAddress = _serverAddress;
timeout.tv_sec = 0;
timeout.tv_usec = 0;
currentClients = 0;
};
private:
bool running;
};
cSocketWrapper Server;
void cSocketWrapper::cClientData::disconnect(){
closesocket(clientSocket);
state = 0;
Server.currentClients--;
cout<<inet_ntoa(clientAddress.sin_addr)<<" has disconnected"<<endl;
};
bool cSocketWrapper::cClientData::getMessage(){
char buffer[2048];
memset(&buffer, 0, sizeof(buffer));
recv(clientSocket, buffer, sizeof(buffer), 0);
cout<<"A message is recieved from "<<inet_ntoa(clientAddress.sin_addr)<<", "<<strlen(buffer)<<" bytes"<<endl;
cout<<"Message "<<buffer<<endl;
};
void cSocketWrapper::acceptConnection(){
fd_set conn;
int nfds = 0;
int clientSizeOf = sizeof(clients->clientAddress);
FD_ZERO(&conn);
FD_SET(listeningSocket.clientSocket, &conn);
nfds = listeningSocket.clientSocket + 1;
if(select(nfds, &conn, NULL, NULL, &timeout)){
for(int t=0; t<200; t++){
if(!clients[t].state){
clients[t].state = 1;
clients[t].clientSocket = accept(listeningSocket.clientSocket, (sockaddr*)&clients[t].clientAddress, &clientSizeOf);
cout<<"Accepted a connection from "<<inet_ntoa(clients[t].clientAddress.sin_addr);
currentClients++;
break;
}
}
}
};
bool cSocketWrapper::setup(){
WSADATA wsaData;
listeningSocket.clientAddress.sin_family = AF_INET;
listeningSocket.clientAddress.sin_addr.s_addr = inet_addr(serverAddress.c_str());
listeningSocket.clientAddress.sin_port = htons(port);
if(WSAStartup(MAKEWORD(1, 0), &wsaData)){
cout<<"<mysock.h> (cSocketWrapper::setup) Error initializing WinSock"<<endl;
return false;
}
cout<<"WinSock initialized successfully"<<endl;
listeningSocket.clientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
bind(listeningSocket.clientSocket, (sockaddr *)&listeningSocket.clientAddress, sizeof(listeningSocket.clientAddress));
listen(listeningSocket.clientSocket, SOMAXCONN);
running = true;
};
void cSocketWrapper::shutdown(){
closesocket(listeningSocket.clientSocket);
for(int t=0; t<200; t++)
if(clients[t].state)
clients[t].disconnect();
WSACleanup();
running = false;
};
void cSocketWrapper::getMessages(){
fd_set inputSet, excSet;
int s;
int nfds = 0;
FD_ZERO(&inputSet);
FD_ZERO(&excSet);
for(int t=0; t<200; t++){
if(clients[t].state){
FD_SET(clients[t].clientSocket, &inputSet);
FD_SET(clients[t].clientSocket, &excSet);
nfds++;
}
}
s = select(nfds,&inputSet,NULL,&excSet,&timeout);
if(s > 0){
for(int t=0; t<200; t++){
if(clients[t].state){
if(FD_ISSET(clients[t].clientSocket,&excSet))
clients[t].disconnect();
if(FD_ISSET(clients[t].clientSocket,&inputSet))
clients[t].getMessage();
};
};
};
};
#endif
Sorry to overwhelm you with code. I am pretty sure the error is in cSocketWrapper::getMessages and / or cSocketWrapper::cClientData::getMessage but I included everything in case it either in't or if you acctually want to compile the program.
Thanks a bunch to anyone who can help. I have only ever done 1 useable program with WinSock and that was years ago, and even then I didn't write the clients in C++.
[Edit: "Use the [source], Luke!"]
[edited by - Oluseyi on April 20, 2004 1:20:47 AM]