From 6b805af42cba72e190d94ffa6d1dd7e44d9dfb61 Mon Sep 17 00:00:00 2001 From: oroborus Date: Fri, 1 Aug 2008 16:53:49 +0000 Subject: - experimentalna podpora TCP - implicitne sa to kompiluje s UDP ( makro SUPPORT_UDP v server.c a client.c ) - ak che niekto skusat TCP, nech si zakomentuje makro SUPPORT_UDP v server.c a client.c a prida makro SUPPORT_TCP - docasna nefunkcnost IPv6 git-svn-id: http://opensvn.csie.org/tuxanci_ng@186 0ee4d065-81f0-4d1e-b06c-ff20ad07cc3e --- src/CMakeLists.txt | 2 +- src/base/arena.c | 4 +- src/base/buffer.c | 127 +++++++++++++++ src/base/buffer.h | 23 +++ src/base/net_multiplayer.c | 10 +- src/base/server.c | 398 +++++++++------------------------------------ src/base/server.h | 20 ++- src/base/tcp_server.c | 286 ++++++++++++++++++++++++++++++++ src/base/tcp_server.h | 15 ++ src/base/udp_server.c | 360 ++++++++++++++++++++++++++++++++++++++++ src/base/udp_server.h | 15 ++ src/client/client.c | 159 +++++++++++++----- src/client/client.h | 4 +- src/net/dns.c | 2 +- src/net/tcp.h | 1 + src/net/udp.c | 2 + src/server/publicServer.c | 4 +- 17 files changed, 1057 insertions(+), 375 deletions(-) create mode 100755 src/base/buffer.c create mode 100755 src/base/buffer.h create mode 100644 src/base/tcp_server.c create mode 100644 src/base/tcp_server.h create mode 100644 src/base/udp_server.c create mode 100644 src/base/udp_server.h (limited to 'src') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 142608f..80a6099 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -3,7 +3,7 @@ SET ( WORKDIR ${CMAKE_SOURCE_DIR}/src ) # find ./ -maxdepth 1 -type f -name \*.c |grep "$" |sed -e 's/^\.\//\$\{WORKDIR\}\/DIR\//' -e 's/\.c//' |tr '\n' ' ' > DIRfiles # nahradte DIR potrebnym adresarem a pak vemte vse co je v DIRfiles a vlozte to sem SET ( SRC_base -${WORKDIR}/base/main ${WORKDIR}/base/shot ${WORKDIR}/base/space ${WORKDIR}/base/checkFront ${WORKDIR}/base/storage ${WORKDIR}/base/myTimer ${WORKDIR}/base/protect ${WORKDIR}/base/list ${WORKDIR}/base/arena ${WORKDIR}/base/server ${WORKDIR}/base/textFile ${WORKDIR}/base/gun ${WORKDIR}/base/arenaFile ${WORKDIR}/base/modules ${WORKDIR}/base/net_multiplayer ${WORKDIR}/base/index ${WORKDIR}/base/item ${WORKDIR}/base/tux ${WORKDIR}/base/director ${WORKDIR}/base/idManager ${WORKDIR}/base/homeDirector ${WORKDIR}/base/proto ${WORKDIR}/base/exportFunction +${WORKDIR}/base/main ${WORKDIR}/base/shot ${WORKDIR}/base/space ${WORKDIR}/base/checkFront ${WORKDIR}/base/storage ${WORKDIR}/base/myTimer ${WORKDIR}/base/protect ${WORKDIR}/base/list ${WORKDIR}/base/arena ${WORKDIR}/base/server ${WORKDIR}/base/udp_server ${WORKDIR}/base/tcp_server ${WORKDIR}/base/textFile ${WORKDIR}/base/gun ${WORKDIR}/base/arenaFile ${WORKDIR}/base/modules ${WORKDIR}/base/net_multiplayer ${WORKDIR}/base/index ${WORKDIR}/base/item ${WORKDIR}/base/tux ${WORKDIR}/base/director ${WORKDIR}/base/idManager ${WORKDIR}/base/homeDirector ${WORKDIR}/base/proto ${WORKDIR}/base/exportFunction ${WORKDIR}/base/buffer ${WORKDIR}/net/udp ${WORKDIR}/net/tcp ${WORKDIR}/net/dns ) diff --git a/src/base/arena.c b/src/base/arena.c index e5c90c0..437f7a6 100644 --- a/src/base/arena.c +++ b/src/base/arena.c @@ -175,10 +175,10 @@ void drawArena(arena_t *arena) getCenterScreen(&screen_x, &screen_y, tux->x, tux->y); for( i = screen_y/arena->background->h ; - i <= screen_y/arena->background->h + WINDOW_SIZE_Y/arena->background->h ; i++ ) + i <= screen_y/arena->background->h + WINDOW_SIZE_Y/arena->background->h+1 ; i++ ) { for( j = screen_x/arena->background->w ; - j <= screen_x/arena->background->w + WINDOW_SIZE_X/arena->background->w ; j++ ) + j <= screen_x/arena->background->w + WINDOW_SIZE_X/arena->background->w+1 ; j++ ) { addLayer(arena->background, j * arena->background->w, diff --git a/src/base/buffer.c b/src/base/buffer.c new file mode 100755 index 0000000..13d3225 --- /dev/null +++ b/src/base/buffer.c @@ -0,0 +1,127 @@ + +#include +#include +#include +#include + +#include "buffer.h" + +buffer_t * newBuffer(int n) +{ + buffer_t *new; + + new = malloc(sizeof(buffer_t)); + memset(new, 0, sizeof(buffer_t)); + new->alloc = n; + new->data = malloc(n); + memset(new->data , 0, n); + + return new; +} + +int addBuffer(buffer_t *p, char *data, int len) +{ + assert( p != NULL ); + assert( data != NULL ); + assert( len >= 0 ); + + if( p->size + len <= p->alloc ) + { + memcpy(p->data + p->size, data, len); + p->size += len; + return 0; + } + + return -1; +} + +int cutBuffer(buffer_t *p, int len) +{ + assert( p != NULL ); + assert( len >= 0 ); + + if( p->size - len >= 0 ) + { + memmove(p->data, p->data + len, p->size - len); + p->size -= len; + return 0; + } + + return -1; +} + +int getBufferCount(buffer_t *p) +{ + char *begin; + char *end; + int count; + int size; + + assert( p != NULL ); + + count = 0; + begin = p->data; + size = p->size; + + while( ( end = memchr(begin, '\n', size) ) != NULL ) + { + count++; + size -= ( (end+1) - begin); + begin = end+1; + } + + //printf("count = %d\n", count); + //printf("data = %s\n", p->data); + return count; +} + +int getBufferLine(buffer_t *p, char *line, int len) +{ + char *end; + int ret_len; + + assert( p != NULL ); + assert( line != NULL ); + assert( len >= 0 ); + + end = NULL; + + end = memchr(p->data, '\n', p->size); + + if( end == NULL ) return -1; + + ret_len = (int) (end - p->data)+1; + if( ret_len > len-1 ) ret_len = len-1; + + memset(line, 0, len); + memcpy(line, p->data, ret_len); + + cutBuffer(p, ret_len); + + return ret_len; +} + +int getBufferData(buffer_t *p, char *line, int len) +{ + assert( p != NULL ); + assert( line != NULL ); + assert( len >= 0 ); + + if( p->size < len ) + { + len = p->size; + } + + memcpy(line, p->data, len); + cutBuffer(p, len); + + return len; +} + +void destroyBuffer(buffer_t *p) +{ + assert( p != NULL ); + + if( p->data != NULL )free(p->data); + free(p); +} diff --git a/src/base/buffer.h b/src/base/buffer.h new file mode 100755 index 0000000..c9cdee5 --- /dev/null +++ b/src/base/buffer.h @@ -0,0 +1,23 @@ + +#ifndef BUFFER_H + +#define BUFFER_H + +#define BUFFER_LIMIT_ALLOC 1024 + +typedef struct str_buffer +{ + char *data; + unsigned int size; + unsigned int alloc; +} buffer_t; + +extern buffer_t * newBuffer(int n); +extern int addBuffer(buffer_t *p, char *data, int len); +extern int cutBuffer(buffer_t *p, int len); +extern int getBufferCount(buffer_t *p); +extern int getBufferLine(buffer_t *p, char *line, int len); +extern int getBufferData(buffer_t *p, char *line, int len); +extern void destroyBuffer(buffer_t *p); + +#endif diff --git a/src/base/net_multiplayer.c b/src/base/net_multiplayer.c index 3404581..f85d287 100644 --- a/src/base/net_multiplayer.c +++ b/src/base/net_multiplayer.c @@ -31,7 +31,7 @@ int getNetTypeGame() return netGameType; } -#ifdef PUBLIC_SERVER +#ifdef OLD_PUBLIC_SERVER int initNetMulitplayerPublicServer(char *ip4, int port4, char *ip6, int port6) { @@ -50,7 +50,7 @@ int initNetMuliplayer(int type, char *ip, int port, int proto) break; case NET_GAME_TYPE_SERVER : - if( initUdpServer(ip, port, proto) != 0 ) + if( initServer(ip, port, proto) != 0 ) { fprintf(stderr, "Unable to inicialize network game as server!\n"); netGameType = NET_GAME_TYPE_NONE; @@ -60,7 +60,7 @@ int initNetMuliplayer(int type, char *ip, int port, int proto) #ifndef PUBLIC_SERVER case NET_GAME_TYPE_CLIENT : - if( initUdpClient(ip, port, proto) != 0 ) + if( initClient(ip, port, proto) != 0 ) { fprintf(stderr, "Unable to inicialize network game as client!\n"); netGameType = NET_GAME_TYPE_NONE; @@ -106,12 +106,12 @@ void quitNetMultiplayer() break; case NET_GAME_TYPE_SERVER : - quitUdpServer(); + quitServer(); break; #ifndef PUBLIC_SERVER case NET_GAME_TYPE_CLIENT : - quitUdpClient(); + quitClient(); break; #endif default : diff --git a/src/base/server.c b/src/base/server.c index 8389d04..b598810 100644 --- a/src/base/server.c +++ b/src/base/server.c @@ -1,28 +1,29 @@ -#include -#include -#include - -#include - -#include -#include -#include - #ifndef __WIN32__ -#include -#include -#include +# include +# include +# include +# include +# include #else -#include -#include +# include +# include #endif +#include +#include +#include +#include +#include +#include + #include "main.h" #include "list.h" #include "tux.h" #include "proto.h" #include "server.h" +#include "udp_server.h" +#include "tcp_server.h" #include "myTimer.h" #include "arena.h" #include "net_multiplayer.h" @@ -39,13 +40,9 @@ #include "heightScore.h" #endif -#include "udp.h" - -static sock_udp_t *sock_server_udp; -static sock_udp_t *sock_server_udp_second; +#define SUPPORT_UDP static list_t *listClient; -static list_t *listClientIndex; static list_t *listServerTimer; static time_t timeUpdate; @@ -112,43 +109,27 @@ time_t getUpdateServer() return time(NULL) - timeUpdate; } -static client_t* newUdpClient(sock_udp_t *sock_udp, sock_udp_t *socket_udp_server) +client_t* newAnyClient() { client_t *new; - char str_ip[STR_IP_SIZE]; - assert( sock_udp != NULL ); - - getSockUdpIp(sock_udp, str_ip, STR_IP_SIZE); - printf("new client from %s %d\n", str_ip, getSockUdpPort(sock_udp)); - new = malloc( sizeof(client_t) ); memset(new, 0, sizeof(client_t)); - + new->status = NET_STATUS_OK; new->listRecvMsg = newList(); new->listSendMsg = newCheckFront(); new->listSeesShot = newList(); new->protect = newProtect(); - new->socket_udp = sock_udp; - new->socket_udp_server = socket_udp_server; return new; } -static void destroyClient(client_t *p) +void destroyAnyClient(client_t *p) { - char str_ip[STR_IP_SIZE]; - assert( p != NULL ); - eventMsgInCheckFront(p); - - getSockUdpIp(p->socket_udp, str_ip, STR_IP_SIZE); - printf("close connect %s %d\n", str_ip, getSockUdpPort(p->socket_udp) ); - - closeUdpSocket(p->socket_udp); - + //eventMsgInCheckFront(p); destroyListItem(p->listRecvMsg, free); destroyListItem(p->listSeesShot, free); destroyCheckFront(p->listSendMsg); @@ -170,12 +151,22 @@ static void eventDelClient(client_t *client) { int offset; - offset = getFormIndex(listClientIndex, getSockUdpPort(client->socket_udp)); + offset = searchListItem(listClient, client); assert( offset != -1 ); - delFromIndex(listClientIndex, getSockUdpPort(client->socket_udp)); - delListItem(listClient, offset, destroyClient); + switch( client->type ) + { + case CLIENT_TYPE_UDP : + delListItem(listClient, offset, destroyUdpClient); + break; + case CLIENT_TYPE_TCP : + delListItem(listClient, offset, destroyTcpClient); + break; + default : + assert( ! "zly typ !"); + break; + } } static void delZombieCLient(void *p_nothink) @@ -208,7 +199,6 @@ static void delZombieCLient(void *p_nothink) i--; } } - } static void eventPeriodicSyncClient(void *p_nothink) @@ -241,7 +231,7 @@ static void eventSendPingClients(void *p_nothink) proto_send_ping_server(PROTO_SEND_ALL, NULL); } -static void setServerTimer() +void setServerTimer() { if( listServerTimer != NULL ) { @@ -256,73 +246,27 @@ static void setServerTimer() addTaskToTimer(listServerTimer, TIMER_PERIODIC, eventSendPingClients, NULL, SERVER_TIME_PING); } - -static void initServer() +int initServer(char *ip, int port, int proto) { + int ret; + startUpdateServer(); listServerTimer = NULL; listClient = newList(); - listClientIndex = newIndex(); setServerMaxClients(SERVER_MAX_CLIENTS); setServerTimer(); -} - -int initUdpServer(char *ip, int port, int proto) -{ - sock_server_udp = bindUdpSocket(ip, port, proto); - sock_server_udp_second = NULL; - - if( sock_server_udp == NULL ) - { - return -1; - } - - initServer(); - - printf("server listen UDP port %s %d\n", ip, port); - - return 0; -} - -#ifdef PUBLIC_SERVER - -int initUdpPublicServer(char *ip4, int port4, char *ip6, int port6) -{ - sock_server_udp = NULL; - sock_server_udp_second = NULL; - if( ip4 != NULL ) - { - sock_server_udp = bindUdpSocket(ip4, port4, PROTO_UDPv4); - - if( sock_server_udp == NULL ) - { - return -1; - } - - printf("server listen UDP port %s %d\n", ip4, port4); - } - - if( ip6 != NULL ) - { - sock_server_udp_second = bindUdpSocket(ip6, port6, PROTO_UDPv6); - - if( sock_server_udp_second == NULL ) - { - return -1; - } - - printf("server listen UDP port %s %d\n", ip6, port6); - } - - initServer(); - - return 0; -} +#ifdef SUPPORT_UDP + ret = initUdpServer(ip, port, proto); +#endif +#ifdef SUPPORT_TCP + ret = initTcpServer(ip, port, proto); #endif + return ret; +} list_t* getListServerClient() { @@ -355,7 +299,23 @@ void sendClient(client_t *p, char *msg) } #endif - ret = writeUdpSocket(p->socket_udp_server, p->socket_udp, msg, strlen(msg)); + switch( p->type ) + { + case CLIENT_TYPE_UDP : + ret = writeUdpSocket(p->socket_udp, p->socket_udp, msg, strlen(msg)); + break; + case CLIENT_TYPE_TCP : + ret = writeTcpSocket(p->socket_tcp, msg, strlen(msg)); + break; + default : + assert( ! "zly typ !"); + break; + } + + if( ret <= 0 ) + { + p->status = NET_STATUS_ZOMBIE; + } } } @@ -520,25 +480,6 @@ void sendInfoCreateClient(client_t *client) } } -static void eventCreateNewUdpClient(sock_udp_t *socket_udp, sock_udp_t *socket_udp_server) -{ - client_t *client; - int offset; - - assert( socket_udp != NULL ); - - client = newUdpClient( socket_udp, socket_udp_server ); - - offset = addToIndex(listClientIndex, getSockUdpPort(client->socket_udp) ); - - if( offset == -1 ) - { - return; - } - - insList(listClient, offset, client); -} - static void eventClientBuffer(client_t *client) { proto_cmd_server_t* protoCmd; @@ -589,220 +530,41 @@ static void eventClientListBuffer() } } -static client_t* findUdpClient(sock_udp_t *sock_udp) -{ - int offset; - - offset = getFormIndex(listClientIndex, getSockUdpPort(sock_udp)); - - if( offset == -1 ) - { - return NULL; - } - - return (client_t *) listClient->list[offset]; - -} - -static void eventClientUdpSelect(sock_udp_t *sock_server) -{ - sock_udp_t *sock_client; - client_t *client; - char listRecvMsg[STR_SIZE]; - bool_t isCreateNewClient; - int ret; - - assert( sock_server != NULL ); - - sock_client = newSockUdp(sock_server->proto); - isCreateNewClient = FALSE; - - memset(listRecvMsg, 0, STR_SIZE); - - ret = readUdpSocket(sock_server, sock_client, listRecvMsg, STR_SIZE-1); - - client = findUdpClient(sock_client); - - if( client == NULL ) - { - if( getCurrentArena()->spaceTux->list->count+1 > maxClients ) - { - destroySockUdp(sock_client); - return; - } - - eventCreateNewUdpClient(sock_client, sock_server); - client = findUdpClient(sock_client); - isCreateNewClient = TRUE; - } - - if( client == NULL ) - { - fprintf(stderr, "Client total not found !\n"); - return; - } - - if( isCreateNewClient == FALSE ) - { - destroySockUdp(sock_client); - } - - if( ret <= 0 ) - { - client->status = NET_STATUS_ZOMBIE; - return; - } - - //printf("add packet >>%s<<\n", listRecvMsg); - addList(client->listRecvMsg, strdup(listRecvMsg) ); -} - -static int selectServerUdpSocket() -{ - struct timeval tv; - fd_set readfds; - fd_set errorfds; - int max_fd; - int ret; - int count; - -#ifndef PUBLIC_SERVER - tv.tv_sec = 0; - tv.tv_usec = 0; -#endif - -#ifdef PUBLIC_SERVER - tv.tv_sec = 0; - tv.tv_usec = 1000; -#endif - - FD_ZERO(&readfds); - FD_ZERO(&errorfds); - - max_fd = 0; - count = 0; - - if( sock_server_udp != NULL ) - { - FD_SET(sock_server_udp->sock, &errorfds); - FD_SET(sock_server_udp->sock, &readfds); - - if( sock_server_udp->sock > max_fd ) - { - max_fd = sock_server_udp->sock; - } - } - - if( sock_server_udp_second != NULL ) - { - FD_SET(sock_server_udp_second->sock, &readfds); - FD_SET(sock_server_udp_second->sock, &errorfds); - - if( sock_server_udp_second->sock > max_fd ) - { - max_fd = sock_server_udp_second->sock; - } - } - - //printf("select..\n"); - -#ifdef PUBLIC_SERVER - if( listClient->count == 0 ) - { - ret = select(max_fd+1, &readfds, (fd_set *)NULL, &errorfds, NULL); - setServerTimer(); - } - else - { - ret = select(max_fd+1, &readfds, (fd_set *)NULL,&errorfds, &tv); - } -#endif - -#ifndef PUBLIC_SERVER - ret = select(max_fd+1, &readfds, (fd_set *)NULL,&errorfds, &tv); -#endif - - if( ret < 0 ) - { - //printf("select ret = %d\n", ret); - return 0; - } - - if( sock_server_udp != NULL ) - { - if( FD_ISSET(sock_server_udp->sock, &readfds) ) - { - eventClientUdpSelect(sock_server_udp); - count = 1; - } - - if( FD_ISSET(sock_server_udp->sock, &errorfds) ) - { - printf("error\n"); - } - } - - if( sock_server_udp_second != NULL ) - { - if( FD_ISSET(sock_server_udp_second->sock, &readfds) ) - { - eventClientUdpSelect(sock_server_udp_second); - count = 1; - } - - if( FD_ISSET(sock_server_udp_second->sock, &errorfds) ) - { - printf("error\n"); - } - } - - return count; -} - void eventServer() { -#ifndef PUBLIC_SERVER - - int count; - -#ifdef SUPPORT_NET_UNIX_UDP - do{ - count = selectServerUdpSocket(); - }while( count > 0 ); +#ifdef SUPPORT_UDP + eventUdpServer(); #endif -#endif - -#ifdef PUBLIC_SERVER - selectServerUdpSocket(); +#ifdef SUPPORT_TCP + eventTcpServer(); #endif eventClientListBuffer(); eventTimer(listServerTimer); } -void quitUdpServer() +void quitServer() { proto_send_end_server(PROTO_SEND_ALL, NULL); assert( listClient != NULL ); - destroyListItem(listClient, destroyClient); - destroyIndex(listClientIndex); +#ifdef SUPPORT_UDP + destroyListItem(listClient, destroyUdpClient); +#endif - destroyTimer(listServerTimer); +#ifdef SUPPORT_TCP + destroyListItem(listClient, destroyTcpClient); +#endif - if( sock_server_udp != NULL ) - { - printf("close port %d\n", getSockUdpPort(sock_server_udp)); - closeUdpSocket(sock_server_udp); - } + destroyTimer(listServerTimer); - if( sock_server_udp_second != NULL ) - { - printf("close port %d\n", getSockUdpPort(sock_server_udp_second)); - closeUdpSocket(sock_server_udp_second); - } +#ifdef SUPPORT_UDP + quitUdpServer(); +#endif - printf("quit UDP port\n"); +#ifdef SUPPORT_TCP + quitTcpServer(); +#endif } diff --git a/src/base/server.h b/src/base/server.h index 8eaf8d1..61d9333 100644 --- a/src/base/server.h +++ b/src/base/server.h @@ -10,6 +10,8 @@ #include "myTimer.h" #include "protect.h" #include "udp.h" +#include "tcp.h" +#include "buffer.h" #ifndef PUBLIC_SERVER #include "interface.h" @@ -23,10 +25,15 @@ #define SERVER_INDEX_ROOT_TUX 0 +#define CLIENT_TYPE_UDP 1 +#define CLIENT_TYPE_TCP 2 + typedef struct client_struct { - sock_udp_t *socket_udp_server; + int type; sock_udp_t *socket_udp; + sock_tcp_t *socket_tcp; + buffer_t *buffer; int status; @@ -40,17 +47,18 @@ typedef struct client_struct list_t *listSeesShot; } client_t; - +extern int initServer(char *ip, int port, int proto); extern time_t getUpdateServer(); -extern int initUdpServer(char *ip, int port, int proto); -extern int initUdpPublicServer(char *ip4, int port4, char *ip6, int port6); +extern client_t* newAnyClient(); +extern void destroyAnyClient(client_t *p); extern list_t* getListServerClient(); extern int getServerMaxClients(); +extern void setServerTimer(); extern void setServerMaxClients(int n); +extern void sendInfoCreateClient(client_t *client); extern void sendClient(client_t *p, char *msg); extern void protoSendClient(int type, client_t *client, char *msg, int type2, int id); -extern void sendInfoCreateClient(client_t *client); extern void eventServer(); -extern void quitUdpServer(); +extern void quitServer(); #endif diff --git a/src/base/tcp_server.c b/src/base/tcp_server.c new file mode 100644 index 0000000..77d8592 --- /dev/null +++ b/src/base/tcp_server.c @@ -0,0 +1,286 @@ +#include +#include +#include + +#include + +#include +#include +#include + +#ifndef __WIN32__ +#include +#include +#include +#else +#include +#include +#endif + +#include "main.h" +#include "list.h" +#include "tux.h" +#include "proto.h" +#include "server.h" +#include "myTimer.h" +#include "arena.h" +#include "net_multiplayer.h" +#include "checkFront.h" +#include "protect.h" +#include "index.h" + +#ifndef PUBLIC_SERVER +#include "screen_world.h" +#endif + +#ifdef PUBLIC_SERVER +#include "publicServer.h" +#include "heightScore.h" +#endif + +#include "tcp.h" +#include "tcp_server.h" + +static sock_tcp_t *sock_server_tcp; +static sock_tcp_t *sock_server_tcp_second; + +client_t* newTcpClient(sock_tcp_t *sock_tcp) +{ + client_t *new; + char str_ip[STR_IP_SIZE]; + + assert( sock_tcp != NULL ); + + getSockTcpIp(sock_tcp, str_ip, STR_IP_SIZE); + printf("new client TCP from %s %d\n", str_ip, getSockTcpPort(sock_tcp)); + + new = newAnyClient(); + new->type = CLIENT_TYPE_TCP; + new->socket_tcp = sock_tcp; + new->buffer = newBuffer(4096); + + return new; +} + +void destroyTcpClient(client_t *p) +{ + char str_ip[STR_IP_SIZE]; + + eventMsgInCheckFront(p); + + getSockTcpIp(p->socket_tcp, str_ip, STR_IP_SIZE); + printf("closeTCP connect %s %d\n", str_ip, getSockTcpPort(p->socket_tcp) ); + + closeTcpSocket(p->socket_tcp); + destroyBuffer(p->buffer); + + destroyAnyClient(p); +} + +int initTcpServer(char *ip, int port, int proto) +{ + sock_server_tcp = bindTcpSocket(ip, port, proto); + sock_server_tcp_second = NULL; + + if( sock_server_tcp == NULL ) + { + return -1; + } + + disableNagle(sock_server_tcp); + printf("server listen TCP port %s %d\n", ip, port); + + return 0; +} + +static void eventNewClient(sock_tcp_t *server_sock) +{ + list_t *listClient; + sock_tcp_t *sock; + client_t *client; + + listClient = getListServerClient(); + sock = getTcpNewClient(server_sock); + disableNagle(sock); + client = newTcpClient(sock); + addList(listClient, client); +} + +static void eventTcpClient(client_t *client) +{ + char buffer[STR_PROTO_SIZE]; + int ret; + + memset(buffer, 0, STR_PROTO_SIZE); + + ret = readTcpSocket(client->socket_tcp, buffer, STR_PROTO_SIZE-1); + + if( ret <= 0 ) + { + client->status = NET_STATUS_ZOMBIE; + return; + } + + addBuffer(client->buffer, buffer, ret); + + while( getBufferLine(client->buffer, buffer, STR_PROTO_SIZE) >= 0 ) + { + addList(client->listRecvMsg, strdup(buffer) ); + } +} + +static int selectServerTcpSocket() +{ + list_t *listClient; + struct timeval tv; + fd_set readfds; + fd_set errorfds; + int max_fd; + int ret; + int count; + int i; + + listClient = getListServerClient(); + +#ifndef PUBLIC_SERVER + tv.tv_sec = 0; + tv.tv_usec = 0; +#endif + +#ifdef PUBLIC_SERVER + tv.tv_sec = 0; + tv.tv_usec = 1000; +#endif + + FD_ZERO(&readfds); + FD_ZERO(&errorfds); + + max_fd = 0; + count = 0; + + if( sock_server_tcp != NULL ) + { + FD_SET(sock_server_tcp->sock, &errorfds); + FD_SET(sock_server_tcp->sock, &readfds); + + if( sock_server_tcp->sock > max_fd ) + { + max_fd = sock_server_tcp->sock; + } + } + + for( i = 0 ; i < listClient->count ; i++ ) + { + client_t *client; + + client = (client_t *)listClient->list[i]; + + if( client->status != NET_STATUS_OK ) + { + continue; + } + + FD_SET(client->socket_tcp->sock, &errorfds); + FD_SET(client->socket_tcp->sock, &readfds); + + if( client->socket_tcp->sock > max_fd ) + { + max_fd = client->socket_tcp->sock; + } + } + + +#ifdef PUBLIC_SERVER + if( listClient->count == 0 ) + { + ret = select(max_fd+1, &readfds, (fd_set *)NULL, &errorfds, NULL); + setServerTimer(); + } + else + { + ret = select(max_fd+1, &readfds, (fd_set *)NULL,&errorfds, &tv); + } +#endif + +#ifndef PUBLIC_SERVER + ret = select(max_fd+1, &readfds, (fd_set *)NULL,&errorfds, &tv); +#endif + + if( ret < 0 ) + { + //printf("select ret = %d\n", ret); + return 0; + } + + if( sock_server_tcp != NULL ) + { + if( FD_ISSET(sock_server_tcp->sock, &readfds) ) + { + eventNewClient(sock_server_tcp); + count = 1; + } + + if( FD_ISSET(sock_server_tcp->sock, &errorfds) ) + { + printf("error\n"); + } + } + + for( i = 0 ; i < listClient->count ; i++ ) + { + client_t *client; + + client = (client_t *)listClient->list[i]; + + if( FD_ISSET(client->socket_tcp->sock, &readfds) ) + { + //printf("eventTcpClient(client);\n"); + eventTcpClient(client); + count = 1; + } + + if( FD_ISSET(client->socket_tcp->sock, &errorfds) ) + { + //printf("error client\n"); + count = 1; + } + } + + return count; +} + +void eventTcpServer() +{ +#ifndef PUBLIC_SERVER + + int count; + +#ifdef SUPPORT_NET_UNIX_UDP + do{ + count = selectServerTcpSocket(); + }while( count > 0 ); +#endif + +#endif + +#ifdef PUBLIC_SERVER + selectServerTcpSocket(); +#endif +} + +void quitTcpServer() +{ + if( sock_server_tcp != NULL ) + { + printf("close port %d\n", getSockTcpPort(sock_server_tcp)); + closeTcpSocket(sock_server_tcp); + } + + if( sock_server_tcp_second != NULL ) + { + printf("close port %d\n", getSockTcpPort(sock_server_tcp_second)); + closeTcpSocket(sock_server_tcp_second); + } + + printf("quit TCP port\n"); +} diff --git a/src/base/tcp_server.h b/src/base/tcp_server.h new file mode 100644 index 0000000..d4dee0a --- /dev/null +++ b/src/base/tcp_server.h @@ -0,0 +1,15 @@ + +#ifndef SERVER_TCP_H + +#define SERVER_TCP_H + +#include "server.h" +#include "tcp.h" + +extern client_t* newTcpClient(sock_tcp_t *sock_tcp); +extern void destroyTcpClient(client_t *p); +extern int initTcpServer(char *ip, int port, int proto); +extern void eventTcpServer(); +extern void quitTcpServer(); + +#endif diff --git a/src/base/udp_server.c b/src/base/udp_server.c new file mode 100644 index 0000000..cb0aaba --- /dev/null +++ b/src/base/udp_server.c @@ -0,0 +1,360 @@ +#include +#include +#include + +#include + +#include +#include +#include + +#ifndef __WIN32__ +#include +#include +#include +#else +#include +#include +#endif + +#include "main.h" +#include "list.h" +#include "tux.h" +#include "proto.h" +#include "server.h" +#include "myTimer.h" +#include "arena.h" +#include "net_multiplayer.h" +#include "checkFront.h" +#include "protect.h" +#include "index.h" + +#ifndef PUBLIC_SERVER +#include "screen_world.h" +#endif + +#ifdef PUBLIC_SERVER +#include "publicServer.h" +#include "heightScore.h" +#endif + +#include "udp.h" +#include "udp_server.h" + +static sock_udp_t *sock_server_udp; +static sock_udp_t *sock_server_udp_second; + +client_t* newUdpClient(sock_udp_t *sock_udp) +{ + client_t *new; + char str_ip[STR_IP_SIZE]; + + assert( sock_udp != NULL ); + + getSockUdpIp(sock_udp, str_ip, STR_IP_SIZE); + printf("new client UDP from %s %d\n", str_ip, getSockUdpPort(sock_udp)); + + new = newAnyClient(); + new->type = CLIENT_TYPE_UDP; + new->socket_udp = sock_udp; + + return new; +} + +void destroyUdpClient(client_t *p) +{ + char str_ip[STR_IP_SIZE]; + + eventMsgInCheckFront(p); + + getSockUdpIp(p->socket_udp, str_ip, STR_IP_SIZE); + printf("close UDP connect %s %d\n", str_ip, getSockUdpPort(p->socket_udp) ); + + destroySockUdp(p->socket_udp); + + destroyAnyClient(p); +} + +int initUdpServer(char *ip, int port, int proto) +{ + sock_server_udp = bindUdpSocket(ip, port, proto); + sock_server_udp_second = NULL; + + if( sock_server_udp == NULL ) + { + return -1; + } + + printf("server listen UDP port %s %d\n", ip, port); + + return 0; +} + +#ifdef OLD_PUBLIC_SERVER + +int initUdpPublicServer(char *ip4, int port4, char *ip6, int port6) +{ + sock_server_udp = NULL; + sock_server_udp_second = NULL; + + if( ip4 != NULL ) + { + sock_server_udp = bindUdpSocket(ip4, port4, PROTO_UDPv4); + + if( sock_server_udp == NULL ) + { + return -1; + } + + printf("server listen UDP port %s %d\n", ip4, port4); + } + + if( ip6 != NULL ) + { + sock_server_udp_second = bindUdpSocket(ip6, port6, PROTO_UDPv6); + + if( sock_server_udp_second == NULL ) + { + return -1; + } + + printf("server listen UDP port %s %d\n", ip6, port6); + } + + initServer(); + + return 0; +} + +#endif + +static void eventCreateNewUdpClient(sock_udp_t *socket_udp) +{ + list_t *listClient; + client_t *client; + + assert( socket_udp != NULL ); + + listClient = getListServerClient(); + + client = newUdpClient(socket_udp); + addList(listClient, client); +} + +static client_t* findUdpClient(sock_udp_t *sock_udp) +{ + list_t *listClient; + int port; + int i; + + port = getSockUdpPort(sock_udp); + listClient = getListServerClient(); + + for( i = 0 ; i < listClient->count ; i++ ) + { + client_t *client; + + client = (client_t *)listClient->list[i]; + + if( getSockUdpPort(client->socket_udp) == port ) + { + return client; + } + } + + return NULL; +} + +static void eventClientUdpSelect(sock_udp_t *sock_server) +{ + sock_udp_t *sock_client; + client_t *client; + char listRecvMsg[STR_SIZE]; + bool_t isCreateNewClient; + int ret; + + assert( sock_server != NULL ); + + sock_client = newSockUdp(sock_server->proto); + isCreateNewClient = FALSE; + + memset(listRecvMsg, 0, STR_SIZE); + + ret = readUdpSocket(sock_server, sock_client, listRecvMsg, STR_SIZE-1); + + client = findUdpClient(sock_client); + + if( client == NULL ) + { + if( getCurrentArena()->spaceTux->list->count+1 > getServerMaxClients() ) + { + destroySockUdp(sock_client); + return; + } + + eventCreateNewUdpClient(sock_client); + client = findUdpClient(sock_client); + isCreateNewClient = TRUE; + } + + if( client == NULL ) + { + fprintf(stderr, "Client total not found !\n"); + return; + } + + if( isCreateNewClient == FALSE ) + { + destroySockUdp(sock_client); + } + + if( ret <= 0 ) + { + client->status = NET_STATUS_ZOMBIE; + return; + } + + //printf("add packet >>%s<<\n", listRecvMsg); + addList(client->listRecvMsg, strdup(listRecvMsg) ); +} + +static int selectServerUdpSocket() +{ + struct timeval tv; + fd_set readfds; + fd_set errorfds; + int max_fd; + int ret; + int count; + +#ifndef PUBLIC_SERVER + tv.tv_sec = 0; + tv.tv_usec = 0; +#endif + +#ifdef PUBLIC_SERVER + tv.tv_sec = 0; + tv.tv_usec = 1000; +#endif + + FD_ZERO(&readfds); + FD_ZERO(&errorfds); + + max_fd = 0; + count = 0; + + if( sock_server_udp != NULL ) + { + FD_SET(sock_server_udp->sock, &errorfds); + FD_SET(sock_server_udp->sock, &readfds); + + if( sock_server_udp->sock > max_fd ) + { + max_fd = sock_server_udp->sock; + } + } + + if( sock_server_udp_second != NULL ) + { + FD_SET(sock_server_udp_second->sock, &readfds); + FD_SET(sock_server_udp_second->sock, &errorfds); + + if( sock_server_udp_second->sock > max_fd ) + { + max_fd = sock_server_udp_second->sock; + } + } + + //printf("select..\n"); + +#ifdef PUBLIC_SERVER + list_t *listClient; + listClient = getListServerClient(); + + if( listClient->count == 0 ) + { + ret = select(max_fd+1, &readfds, (fd_set *)NULL, &errorfds, NULL); + setServerTimer(); + } + else + { + ret = select(max_fd+1, &readfds, (fd_set *)NULL,&errorfds, &tv); + } +#endif + +#ifndef PUBLIC_SERVER + ret = select(max_fd+1, &readfds, (fd_set *)NULL,&errorfds, &tv); +#endif + + if( ret < 0 ) + { + //printf("select ret = %d\n", ret); + return 0; + } + + if( sock_server_udp != NULL ) + { + if( FD_ISSET(sock_server_udp->sock, &readfds) ) + { + eventClientUdpSelect(sock_server_udp); + count = 1; + } + + if( FD_ISSET(sock_server_udp->sock, &errorfds) ) + { + printf("error\n"); + } + } + + if( sock_server_udp_second != NULL ) + { + if( FD_ISSET(sock_server_udp_second->sock, &readfds) ) + { + eventClientUdpSelect(sock_server_udp_second); + count = 1; + } + + if( FD_ISSET(sock_server_udp_second->sock, &errorfds) ) + { + printf("error\n"); + } + } + + return count; +} + +void eventUdpServer() +{ +#ifndef PUBLIC_SERVER + + int count; + +#ifdef SUPPORT_NET_UNIX_UDP + do{ + count = selectServerUdpSocket(); + }while( count > 0 ); +#endif + +#endif + +#ifdef PUBLIC_SERVER + selectServerUdpSocket(); +#endif +} + +void quitUdpServer() +{ + if( sock_server_udp != NULL ) + { + printf("close port %d\n", getSockUdpPort(sock_server_udp)); + closeUdpSocket(sock_server_udp); + } + + if( sock_server_udp_second != NULL ) + { + printf("close port %d\n", getSockUdpPort(sock_server_udp_second)); + closeUdpSocket(sock_server_udp_second); + } + + printf("quit UDP port\n"); +} diff --git a/src/base/udp_server.h b/src/base/udp_server.h new file mode 100644 index 0000000..58bb018 --- /dev/null +++ b/src/base/udp_server.h @@ -0,0 +1,15 @@ + +#ifndef SERVER_UDP_H + +#define SERVER_UDP_H + +#include "server.h" +#include "udp.h" + +extern client_t* newUdpClient(sock_udp_t *sock_udp); +extern void destroyUdpClient(client_t *p); +extern int initUdpServer(char *ip, int port, int proto); +extern void eventUdpServer(); +extern void quitUdpServer(); + +#endif diff --git a/src/client/client.c b/src/client/client.c index a0b59c4..f6dbe3b 100644 --- a/src/client/client.c +++ b/src/client/client.c @@ -28,12 +28,16 @@ #include "screen_world.h" #include "udp.h" +#include "tcp.h" +#include "buffer.h" -static int protocolType; +#define SUPPORT_UDP static sock_udp_t *sock_server_udp; +static sock_tcp_t *sock_server_tcp; -static list_t *clientBuffer; +static list_t *listRecvMsg; +static buffer_t *clientBuffer; static my_time_t lastPing; static my_time_t lastPingServerAlive; @@ -83,31 +87,61 @@ static proto_cmd_client_t* findCmdProto(char *msg) return NULL; } -static void initClient() +static int initUdpClient(char *ip, int port, int proto) { - char name[STR_NAME_SIZE]; + sock_server_udp = connectUdpSocket(ip, port, proto); - clientBuffer = newList(); - lastPing = getMyTime(); - lastPingServerAlive = getMyTime(); + if( sock_server_udp == NULL ) + { + return -1; + } - getSettingNameRight(name); - proto_send_hello_client(name); + printf("connect UDP %s %d\n", ip, port); + + return 0; } -int initUdpClient(char *ip, int port, int proto) +static int initTcpClient(char *ip, int port, int proto) { - sock_server_udp = connectUdpSocket(ip, port, proto); + sock_server_tcp = connectTcpSocket(ip, port, proto); - if( sock_server_udp == NULL ) + if( sock_server_tcp == NULL ) { return -1; } - printf("connect UDP %s %d\n", ip, port); + disableNagle(sock_server_tcp); - protocolType = NET_PROTOCOL_TYPE_UDP; - initClient(); + printf("connect TCP %s %d\n", ip, port); + + return 0; +} + +int initClient(char *ip, int port, int proto) +{ + char name[STR_NAME_SIZE]; + int ret; + + listRecvMsg = newList(); + lastPing = getMyTime(); + lastPingServerAlive = getMyTime(); + clientBuffer = newBuffer(4096); + +#ifdef SUPPORT_UDP + ret = initUdpClient(ip, port, proto); +#endif + +#ifdef SUPPORT_TCP + ret = initTcpClient(ip, port, proto); +#endif + + if( ret < 0 ) + { + return -1; + } + + getSettingNameRight(name); + proto_send_hello_client(name); return 0; } @@ -125,7 +159,13 @@ void sendServer(char *msg) } #endif +#ifdef SUPPORT_UDP ret = writeUdpSocket(sock_server_udp, sock_server_udp, msg, strlen(msg)); +#endif + +#ifdef SUPPORT_TCP + ret = writeTcpSocket(sock_server_tcp, msg, strlen(msg)); +#endif } static int eventServerSelect() @@ -135,14 +175,28 @@ static int eventServerSelect() memset(buffer, 0, STR_PROTO_SIZE); +#ifdef SUPPORT_UDP ret = readUdpSocket(sock_server_udp, sock_server_udp, buffer, STR_PROTO_SIZE-1); +#endif - if( ret < 0 ) +#ifdef SUPPORT_TCP + ret = readTcpSocket(sock_server_tcp, buffer, STR_PROTO_SIZE-1); +#endif + + if( ret <= 0 ) { return ret; } - addList(clientBuffer, strdup(buffer) ); + addBuffer(clientBuffer, buffer, ret); + + while( getBufferLine(clientBuffer, buffer, STR_PROTO_SIZE) >= 0 ) + { + if( strlen(buffer) > 0) + { + addList(listRecvMsg, strdup(buffer) ); + } + } return ret; } @@ -155,11 +209,11 @@ static void eventServerBuffer() /* obsluha udalosti od servera */ - assert( clientBuffer != NULL ); + assert( listRecvMsg != NULL ); - for( i = 0 ; i < clientBuffer->count ; i++ ) + for( i = 0 ; i < listRecvMsg->count ; i++ ) { - line = (char *)clientBuffer->list[i]; + line = (char *)listRecvMsg->list[i]; protoCmd = findCmdProto(line); #ifndef PUBLIC_SERVER @@ -175,8 +229,8 @@ static void eventServerBuffer() } } - destroyListItem(clientBuffer, free); - clientBuffer = newList(); + destroyListItem(listRecvMsg, free); + listRecvMsg = newList(); } static void eventPingServer() @@ -206,11 +260,12 @@ static bool_t isServerAlive() return TRUE; } -static void selectClientUdpSocket() +static void selectClientSocket() { fd_set readfds; struct timeval tv; int max_fd; + int sock; bool_t isNext; if( isServerAlive() == FALSE ) @@ -228,15 +283,25 @@ static void selectClientUdpSocket() tv.tv_usec = 0; FD_ZERO(&readfds); - FD_SET(sock_server_udp->sock, &readfds); - max_fd = sock_server_udp->sock; - + +#ifdef SUPPORT_UDP + sock = sock_server_udp->sock; +#endif + +#ifdef SUPPORT_TCP + sock = sock_server_tcp->sock; +#endif + + FD_SET(sock, &readfds); + max_fd = sock; select(max_fd+1, &readfds, (fd_set *)NULL, (fd_set *)NULL, &tv); - if( FD_ISSET(sock_server_udp->sock, &readfds) ) + if( FD_ISSET(sock, &readfds) ) { - eventServerSelect(); - isNext = TRUE; + if( eventServerSelect() > 0 ) + { + isNext = TRUE; + } } }while( isNext == TRUE ); @@ -245,23 +310,39 @@ static void selectClientUdpSocket() void eventClient() { eventPingServer(); - selectClientUdpSocket(); + selectClientSocket(); eventServerBuffer(); } -static void quitClient() +static void quitUdpClient() { - proto_send_end_client(); - assert( clientBuffer != NULL ); - destroyListItem(clientBuffer, free); + assert( sock_server_udp != NULL ); + closeUdpSocket(sock_server_udp); + + printf("quit UDP conenct\n"); } -void quitUdpClient() +static void quitTcpClient() { - quitClient(); + assert( sock_server_tcp != NULL ); + closeTcpSocket(sock_server_tcp); - assert( sock_server_udp != NULL ); - closeUdpSocket(sock_server_udp); + printf("quit TCP conenct\n"); +} - printf("quit UDP conenct\n"); +void quitClient() +{ + proto_send_end_client(); + assert( listRecvMsg != NULL ); + destroyListItem(listRecvMsg, free); + destroyBuffer(clientBuffer); + +#ifdef SUPPORT_UDP + quitUdpClient(); +#endif + +#ifdef SUPPORT_TCP + quitTcpClient(); +#endif } + diff --git a/src/client/client.h b/src/client/client.h index e301c4b..32ae6e5 100644 --- a/src/client/client.h +++ b/src/client/client.h @@ -9,10 +9,10 @@ #define CLIENT_TIMEOUT 1000 #define SERVER_TIMEOUT_ALIVE 5000 -extern int initUdpClient(char *ip, int port, int proto); +extern int initClient(char *ip, int port, int proto); extern void sendServer(char *msg); extern void eventClient(); -extern void quitUdpClient(); +extern void quitClient(); #endif diff --git a/src/net/dns.c b/src/net/dns.c index 657bbea..84c917a 100644 --- a/src/net/dns.c +++ b/src/net/dns.c @@ -18,7 +18,7 @@ char* getIPFormDNS(char *domain) host = gethostbyname(domain); - if( host == NULL || host->h_addr_list[0] == NULL ) + if( host == NULL || host->h_addr_list[0] == NULL ) { return NULL; } diff --git a/src/net/tcp.h b/src/net/tcp.h index 8c436c3..b7ea55b 100644 --- a/src/net/tcp.h +++ b/src/net/tcp.h @@ -28,6 +28,7 @@ extern sock_tcp_t* getTcpNewClient(sock_tcp_t *p); extern void getSockTcpIp(sock_tcp_t *p, char *str_ip, int len); extern int getSockTcpPort(sock_tcp_t *p); extern sock_tcp_t* connectTcpSocket(char *ip, int port, int proto); +extern int disableNagle(sock_tcp_t *p); extern int readTcpSocket(sock_tcp_t *p, void *address, int len); extern int writeTcpSocket(sock_tcp_t *p, void *address, int len); extern void closeTcpSocket(sock_tcp_t *p); diff --git a/src/net/udp.c b/src/net/udp.c index 6ab3573..7b8afba 100644 --- a/src/net/udp.c +++ b/src/net/udp.c @@ -218,6 +218,8 @@ int readUdpSocket(sock_udp_t *src, sock_udp_t *dst, void *address, int len) } #endif + dst->sock = src->sock; + if( size < 0 ) { char str_ip[STR_IP_SIZE]; diff --git a/src/server/publicServer.c b/src/server/publicServer.c index e24e1a8..637ac54 100644 --- a/src/server/publicServer.c +++ b/src/server/publicServer.c @@ -228,7 +228,9 @@ static int initPublicServerNetwork() port4 = atoi( getSetting("PORTv4", "--port", "2200") ); port6 = atoi( getSetting("PORTv6", "--port", "2200") ); - ret = initNetMulitplayerPublicServer(p_ip4, port4, p_ip6, port6); + //ret = initNetMulitplayerPublicServer(p_ip4, port4, p_ip6, port6); + + ret = initNetMuliplayer(NET_GAME_TYPE_SERVER, p_ip4, port4, PROTO_TCPv4); return ret; } -- cgit v1.2.3