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/base/udp_server.c | 360 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 360 insertions(+) create mode 100644 src/base/udp_server.c (limited to 'src/base/udp_server.c') 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"); +} -- cgit v1.2.3