Chat LIVE With Programming Experts! There Are 23 Online Right Now...

Welcome to Dream.In.Code
Become a C++ Expert!

Join 244,284 C++ Programmers for FREE! Get instant access to thousands of C++ experts, tutorials, code snippets, and more! There are 1,022 people online right now. Registration is fast and FREE... Join Now!




winsock help C++ (Solved)

 
Reply to this topicStart new topic

winsock help C++ (Solved)

Keegan
21 Dec, 2008 - 03:53 PM
Post #1

New D.I.C Head
*

Joined: 21 Dec, 2008
Posts: 1

CODE
#include <SDL/SDL.h>
#include <SDL_gfxPrimitives.h>
#include "sdl_functs.h" //Few things
#include <winsock2.h>
#include <zlib.h>
#include "ansi_colors_etc.h" //Included ANSI colors and IAC codes
#include <iostream>
//#include "afflictions.h" Ignore these headers...
//#include "system_checks.h"

using namespace std; //For strings.

SOCKET listensock;
SOCKET connectsock;
SOCKET clients[3];
sockaddr * client_sock[3];
int accepted_client = 0;
int sys_init();

bool sdl_loop();
int winsock_init();
int winsock_bindsock();
int winsock_accept_connection();
int to_client(char str[]);
int to_server(char str[]);
char* str_to_chr(string);
string recv_from_client();
string recv_from_server();

int main (int argc, char** argv) {
//    sys_init();
    int e = winsock_init();
    if (e != 1) {printf("Winsock error: %d", e); return 1;}
    e = winsock_bindsock();
    if (e != 1) {printf("Failed to bind listensock."); WSACleanup (); return 1;}
    if ( SDL_Init( SDL_INIT_EVERYTHING ) < 0 )
    {
        printf( "Unable to init SDL: %s\n", SDL_GetError() );
        WSACleanup ();
        return 1;
    }

    // make sure SDL cleans up before exit
    atexit(SDL_Quit);
    SDL_Surface* screen = SDL_SetVideoMode(320, 500, 16,
                                           SDL_HWSURFACE|SDL_DOUBLEBUF);
    SDL_WM_SetCaption( "Keegan's System", NULL );
    if ( !screen )
    {
        printf("Unable to set 320x500 video: %s\n", SDL_GetError());
        WSACleanup ();
        return 1;
    }
    SDL_Surface *map_surface = SDL_CreateRGBSurface(SDL_SWSURFACE, 200, 200, 32, 0, 0, 0, 0);
    boxRGBA(screen,118,109,320,310,0,0,255,255); //Draw the blue square below the map.
    apply_surface(119,110,map_surface,screen);
    bool done = false;
    int sent = 0;
    while (!done)
    {
     done = sdl_loop();
     int e = winsock_accept_connection(); if (e == -1) {done = true;}
     if (clients[0]) { //If we have a client that decided to connect? :D
       string activestr;
       activestr = recv_from_client();
       if (activestr == "-1") {to_server("QQ"); closesocket(connectsock); closesocket(clients[0]);} else // This is how Itried to fix it.
       if (activestr != "") {to_server(str_to_chr(activestr));}
       activestr = recv_from_server();
       if (activestr == "-1") {to_client(C_R"["C_W"Sys"C_R"]"C_0": Disconnected from server."C_0); closesocket(connectsock); closesocket(clients[0]);} else // Same for server.
       if (activestr != "") {to_client(str_to_chr(activestr));}
     }
     SDL_Flip(screen);
     Sleep(30);
    }
    SDL_FreeSurface(map_surface);
    SDL_FreeSurface(screen);
    WSACleanup ();
    return 0;
}


int winsock_init() {
    WSADATA w;
    int error = WSAStartup (0x0202, &w);
    if (error)
    {
     return -1;
    }
    if (w.wVersion != 0x0202)
    {
     WSACleanup ();
     return 0;
    }
    return 1;
}

int winsock_bindsock() {
    listensock = socket (AF_INET, SOCK_STREAM, 0);
    sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons (5558);
    addr.sin_addr.s_addr = htonl (INADDR_ANY);
    if (bind(listensock, (LPSOCKADDR)&addr, sizeof(addr)) == SOCKET_ERROR) {return 0;}
    if (listen(listensock,5)==SOCKET_ERROR) { return 0;}
    return 1;
}

string recv_from_client() {
string mstr;
mstr = "";
fd_set socketSet;
FD_ZERO(&socketSet);
FD_SET(clients[0], &socketSet);
timeval timeout = {0,0};
int a=select(0,&socketSet,NULL,NULL,&timeout);
if (a == 0) {return "";} else if (a < 0) {return "-1";} //Hm!
while (a > 0) {
   char str[1];
   recv (clients[0], str, 1,0);
   mstr += str;
   a = select(0,&socketSet,NULL,NULL,&timeout);
}
return mstr;
}
string recv_from_server() {
string mstr;
mstr = "";
fd_set socketSet;
FD_ZERO(&socketSet);
FD_SET(connectsock, &socketSet);
timeval timeout = {0,0};
int a=select(0,&socketSet,NULL,NULL,&timeout);
if (a == 0) {return "";} else if (a < 0) {return "-1";}
while (a > 0) {
   char str[1];
   recv (connectsock, str, 1,0);
   mstr += str;
   a = select(0,&socketSet,NULL,NULL,&timeout);
}
return mstr;
}

int winsock_accept_connection() {
fd_set socketSet;
FD_ZERO(&socketSet);
FD_SET(listensock, &socketSet);
timeval timeout = {0,0};
if (int a=select(0,&socketSet,NULL,NULL,&timeout) != 0) {
  clients[accepted_client] =  // accept a connection
      accept (listensock, NULL, NULL);

  if (clients[accepted_client] == INVALID_SOCKET) {
      return 0; // No new client.
  } else if (accepted_client < 1) {
      //Client connected successfully and there was currently no other clients.
      char returnstr[] = C_R"["C_W"Welcome to Achaea."C_R"]\r\n"C_0;
      send (clients[accepted_client], returnstr, sizeof(returnstr), 0);
      accepted_client++;
      connectsock = socket (AF_INET, SOCK_STREAM, 0);
      sockaddr_in target;
      target.sin_family = AF_INET;
      //target.sin_port = htons (5555);
      target.sin_port = htons (23);
      //target.sin_addr.s_addr = inet_addr ("127.0.0.1");
      target.sin_addr.s_addr = inet_addr ("64.127.116.163");
      if (connect(connectsock,(SOCKADDR*)&target, sizeof(target)) == SOCKET_ERROR) {return -1;}
      return 1;
  } else {
    char buffer[] = C_R"["C_W"Sys"C_R"]"C_0": Already have someone connected, later.\r\n";
    send(clients[accepted_client], buffer, sizeof(buffer), 0);
    closesocket(clients[accepted_client]);
    return 0;
  }
} else if (a == 0) {return 0;} else {return 0;}
}

bool sdl_loop() {
        // message processing loop
        SDL_Event event;
        while (SDL_PollEvent(&event))
        {
            // check for messages
            switch (event.type)
            {
                // exit if the window is closed
            case SDL_QUIT:
                return true;
                break;

                // check for keypresses
            case SDL_KEYDOWN:
                {
                    // exit if ESCAPE is pressed
                    if (event.key.keysym.sym == SDLK_ESCAPE)
                        return true;
                    break;
                }
            } // end switch
        } // end of message processing
        return false;

}

int to_client(char str[]) {
    send (clients[0], str, strlen(str), 0);
    return 1;
}

int to_server(char str[]) {
    send (connectsock, str, strlen(str), 0);
    return 1;
}

char * str_to_chr(string mystr) {
    char *returnstr=new char[mystr.length()+1];
    strcpy(returnstr,mystr.c_str());
    return returnstr;
}


Having a rather annoying problem.
This is designed to be a telnet proxy, for connecting to a specific MUD. It works fine except for when I get disconnected or do @quit, during which events it locks the app up. Haven't added MCCP, etcetera support, yet.

I'm rather new at using winsock, so I'm not really sure how I'm supposed to deal with this. Any help would be appreciated!

Not sure how to even handle disconnects sad.gif








Edit: Nevermind, fixed. Apparently select wasn't returning that the socket closed, however recv was returning 0, which means the socket was indeed closed. Good to know.

This post has been edited by Keegan: 21 Dec, 2008 - 05:25 PM

User is offlineProfile CardPM
+Quote Post

Reply to this topicStart new topic

Time is now: 7/4/09 02:55PM

Live C++ Help!

Be Social

Dream.In.Code RSS Feed Dream.In.Code LinkedIn Group Follow Us On Twitter Fan Us On Facebook

C++ Tutorials

Reference Sheets

C++ Snippets

DIC Chatroom

Bye Bye Ads

Monthly Drawing

Thumb Drive

Top Contributors

Top 10 Kudos This Month