Skip to main content
gamedev.net
🔒 Locked

WinSock problems

Started by gandolf1212 Apr 20, 2004 at 12:07 AM 1 replies 500+ views
Original Post
gandolf1212
gandolf1212
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]
I think there's to much blood in my caffeine system.
foofightr
foofightr
"my program dies"

You''ll need to do better than 3 words if you want anyone to help you.
gandolf1212
gandolf1212
How about the other 3 words in the sentence you ingnored? How about the few pages of code?

Alright. When somone disconnects, the program just starts spamming that "so and so ip has a message". It appears to go into an infinite loop.
I think there's to much blood in my caffeine system.

Topic Locked

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

Sign in to reply to this topic.