E:/Eigene Dateien/Eigene Projekte/c0re/Network.cpp

Go to the documentation of this file.
00001 /*
00002         This file is part of c0re.
00003 
00004         c0re is a multiplayer RTS on a hexagonal map with an evolving unit concept.
00005     Copyright (C) 2007 Stephan Hofmann
00006 
00007     c0re is free software: you can redistribute it and/or modify
00008     it under the terms of the GNU General Public License as published by
00009     the Free Software Foundation, either version 3 of the License, or
00010     (at your option) any later version.
00011 
00012     This program is distributed in the hope that it will be useful,
00013     but WITHOUT ANY WARRANTY; without even the implied warranty of
00014     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015     GNU General Public License for more details.
00016 
00017     You should have received a copy of the GNU General Public License
00018     along with this program.  If not, see <http://www.gnu.org/licenses/>.
00019 */
00020 
00021 #include "Network.h"
00022 
00023 #include "system.h"
00024 #include <winsock.h>
00025 #include <iostream>
00026 
00027 Network::Network(Level* p_level)
00028 {
00029         level = p_level;
00030         conSocket = INVALID_SOCKET;
00031 }
00032 
00033 Network::~Network()
00034 {
00035 }
00036 
00037 bool Network::createServer(std::string p_level_name, std::string p_player_name, int p_port)
00038 {
00039         bool ret = false;
00040 
00041         //create listen socket
00042         SOCKET listenSocket = _createServer(p_port);
00043         if (listenSocket == INVALID_SOCKET)
00044                 return false;
00045         
00046         //wait for connection
00047         while (conSocket == INVALID_SOCKET)
00048         {
00049                 //accept conection
00050                 std::string ip_add;
00051                 while (conSocket == INVALID_SOCKET)
00052                 {
00053                         conSocket = _acceptConnection(listenSocket, ip_add);
00054                         sleep(10); //Wait 10ms
00055                 }
00056                 int waitCounter = 200; //20 times will give a chance
00057                 while (waitCounter > 0)
00058                 {
00059                         if (_test(conSocket) >= 8)
00060                                 waitCounter = 0; //we got the first 8 bytes in time
00061                         waitCounter--;
00062                         sleep(100); //wait 100ms
00063                 }
00064                 
00065                 //now test if it is the right message
00066                 if (_test(conSocket) < 8)
00067                 {
00068                         _closeConnection(conSocket);
00069                 }
00070                 else
00071                 {       // fetch 8 bytes
00072                         char buffer[MAXBUFFER];
00073                         if (_recv(conSocket, buffer, 8) == 8)
00074                         {
00075                                 buffer[8] = (char) 0; // we end the string
00076                                 if (strcmp(buffer, "##c0re##") == 0)
00077                                 {
00078                                         ret = true;
00079                                         //now sed the same msg back
00080                                         _send(conSocket, buffer, 8);
00081                                         //now send level_name
00082                                         sprintf_s(buffer, "%255s", p_level_name.c_str());
00083                                         _send(conSocket, buffer, 255);
00084                                 }
00085                                 else //wrong message
00086                                         _closeConnection(conSocket);
00087                         }
00088                         else //some socket error
00089                                 _closeConnection(conSocket);
00090                 }
00091         }
00092         //and close listen Socket
00093         _closeConnection(listenSocket);
00094         return ret;
00095 }
00096 
00097 std::string Network::connect(std::string p_player_name, std::string p_address, int p_port)
00098 {
00099         std::string ret = "";
00100         //just connect
00101         conSocket = _connect(p_address, p_port);
00102         if (conSocket != INVALID_SOCKET)
00103         {
00104                 char buffer[MAXBUFFER];
00105                 sprintf_s(buffer, "##c0re##");
00106                 //and send msg
00107                 _send(conSocket, buffer, 8);
00108 
00109                 //now wait for return message
00110                 int waitCounter = 200; //200 times will give a chance
00111                 while (waitCounter > 0)
00112                 {
00113                         if (_test(conSocket) >= 263)
00114                                 waitCounter = 0; //we got the first 8 bytes in time
00115                         waitCounter--;
00116                         sleep(100); //wait 100ms
00117                 }
00118                 
00119                 //now test if it is the right message
00120                 if (_test(conSocket) < 263)
00121                 {
00122                         _closeConnection(conSocket);
00123                 }
00124                 else
00125                 {       // fetch 8 bytes
00126                         char buffer[MAXBUFFER];
00127                         if (_recv(conSocket, buffer, 8) == 8)
00128                         {
00129                                 buffer[8] = (char) 0; // we end the string
00130                                 if (strcmp(buffer, "##c0re##") != 0)
00131                                 {
00132                                         //wrong message
00133                                         _closeConnection(conSocket);
00134                                         return "";
00135                                 }
00136                                 else
00137                                 {
00138                                         //right message ow fetch the level_name
00139                                         if (_recv(conSocket, buffer, 255) == 255)
00140                                         {
00141                                                 buffer[255] = (char) 0;
00142                                                 ret = buffer;
00143                                                 //now delete headening spaces
00144                                                 while (ret.find(" ") == 0)
00145                                                         ret.erase(0, 1);
00146                                         }
00147                                         else
00148                                         {
00149                                                 //bad error
00150                                                 _closeConnection(conSocket);
00151                                                 return "";
00152                                         }
00153                                 }
00154                         }
00155                         else //some socket error
00156                                 _closeConnection(conSocket);
00157                 }
00158         }
00159 
00160         return ret;
00161 }
00162 
00163 
00164 bool Network::waitForRemoteSide()
00165 {
00166         bool ret = false;
00167 
00168         //send "done"
00169 
00170         //wait for "done"
00171 
00172         return ret;
00173 }
00174 
00175 
00176 /*** Wrapper functios***/
00177 
00178 
00179 long Network::_send(SOCKET p_socket, char p_buffer[MAXBUFFER], long p_size)
00180 {
00181         long ret = -1;
00182         if (send(p_socket, p_buffer, p_size, 0) != SOCKET_ERROR)
00183                 ret = 0;
00184         return ret;
00185 }
00186 
00187 long Network::_test(SOCKET p_socket)
00188 {
00189         int ret;
00190         if (ioctlsocket(p_socket, FIONREAD, (u_long*) &ret) == SOCKET_ERROR)
00191                  ret = -1;
00192         return ret;
00193 }
00194 
00195 long Network::_recv(SOCKET p_socket, char p_buffer[MAXBUFFER], long p_maxsize)
00196 {
00197         long ret = -1;
00198         if (recv(p_socket, p_buffer, p_maxsize, 0) != SOCKET_ERROR)
00199                 ret = p_maxsize;
00200         return ret;
00201 }
00202 
00203 SOCKET Network::_acceptConnection(SOCKET p_socket, std::string & p_ipAddress)
00204 {
00205         SOCKET ret = INVALID_SOCKET;
00206         struct sockaddr_in  cli;
00207 
00208         int cli_size = sizeof(cli);
00209         ret = accept(p_socket,(struct sockaddr*) &cli, &cli_size);
00210 
00211         if (ret == INVALID_SOCKET)
00212                 return ret = -1;
00213 
00214         p_ipAddress = inet_ntoa(cli.sin_addr);
00215         
00216         return ret;
00217 }
00218 
00219 int Network::_closeConnection(SOCKET &p_socket)
00220 {
00221         int ret = -1;
00222         closesocket(p_socket);
00223         p_socket = INVALID_SOCKET;
00224         return ret;
00225 }
00226 
00227 SOCKET Network::_createServer(int p_port)
00228 {
00229         SOCKET ret = INVALID_SOCKET;
00230         struct sockaddr_in srv;
00231 
00232         WSADATA wsa;
00233         if (WSAStartup(MAKEWORD(1, 1), &wsa))
00234         {
00235                 printf("WSAStartup() failed, %lu\n", (unsigned long)GetLastError());
00236         }
00237 
00238         ret = socket(AF_INET, SOCK_STREAM, 0);
00239         if (ret == INVALID_SOCKET)
00240         {
00241                 std::cout <<"socket() failed\n";
00242                 return ret;
00243         }
00244 
00245         srv.sin_addr.s_addr = INADDR_ANY;
00246         srv.sin_port = htons( (unsigned short int) p_port);
00247         srv.sin_family = AF_INET;
00248 
00249         if (bind(ret,(struct sockaddr*) &srv, sizeof(srv)) == -1)
00250         {
00251                 std::cout << "bind() failed\n";
00252                 return ret = INVALID_SOCKET;
00253         }
00254 
00255         if (listen(ret, 3) == INVALID_SOCKET)
00256         {
00257                 std::cout << "listen() failed\n";
00258                 return ret = INVALID_SOCKET;
00259         }
00260 
00261         long toll;
00262         int i = ioctlsocket(ret,FIONBIO,(u_long*) &toll);
00263         if (i != 0)
00264         {
00265                 std::cout << "unblocking failed\n";
00266                 return ret = INVALID_SOCKET;
00267         }
00268 
00269         return ret;
00270 }
00271 
00272 SOCKET Network::_connect(std::string p_ipAddress, int p_port)
00273 {
00274         SOCKET ret = INVALID_SOCKET;
00275         struct sockaddr_in srv;
00276 
00277         WSADATA wsa;
00278         if (WSAStartup(MAKEWORD(1, 1), &wsa))
00279         {
00280                 printf("WSAStartup() failed, %lu\n", (unsigned long)GetLastError());
00281                 ret = -1;
00282         }
00283 
00284 
00285         ret = socket(AF_INET, SOCK_STREAM, 0);
00286         if (ret == -1)
00287         {
00288                 std::cout << "socket() failed\n";
00289                 return ret;
00290         }
00291 
00292         srv.sin_addr.s_addr = inet_addr(p_ipAddress.c_str());
00293         srv.sin_port = htons( (unsigned short int) p_port);
00294         srv.sin_family = AF_INET;
00295 
00296         if (::connect(ret,(struct sockaddr*) &srv, sizeof(srv)) == -1)
00297         {
00298                 std::cout << "connect() failed\n";
00299                 return ret = -1;
00300         }
00301 
00302         long toll;
00303         int i = ioctlsocket(ret,FIONBIO,(u_long*) &toll);
00304         if (i != 0)
00305         {
00306                 std::cout << "unblocking failed\n";
00307                 return ret = -1;
00308         }
00309 
00310         return ret;
00311 }

Generated on Tue Jul 17 22:02:22 2007 for C0re by  doxygen 1.5.2