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

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