diff options
| author | oroborus <oroborus@0ee4d065-81f0-4d1e-b06c-ff20ad07cc3e> | 2008-06-28 16:38:35 +0000 |
|---|---|---|
| committer | oroborus <oroborus@0ee4d065-81f0-4d1e-b06c-ff20ad07cc3e> | 2008-06-28 16:38:35 +0000 |
| commit | 2d776fcd61be168e1ff0ff2e4a5e71835e7cea19 (patch) | |
| tree | 7cf274897bf540d5332d446f583ffd066e4e2e1d /src/net_unix/udp.c | |
| parent | b877ae23ac5d380ab3aa48d7724045cf4883b186 (diff) | |
- prekopanie adresarovej struktury, prva cast
git-svn-id: http://opensvn.csie.org/tuxanci_ng@77 0ee4d065-81f0-4d1e-b06c-ff20ad07cc3e
Diffstat (limited to 'src/net_unix/udp.c')
| -rw-r--r-- | src/net_unix/udp.c | 358 |
1 files changed, 358 insertions, 0 deletions
diff --git a/src/net_unix/udp.c b/src/net_unix/udp.c new file mode 100644 index 0000000..a701d48 --- /dev/null +++ b/src/net_unix/udp.c @@ -0,0 +1,358 @@ + + +#include <sys/socket.h> +#include <sys/types.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <netdb.h> +#include <unistd.h> +#include <stdlib.h> +#include <string.h> +#include <stdio.h> +#include <netdb.h> +#include <string.h> +#include <assert.h> + +#define BUFSIZE 1000 + +#include "base/main.h" +#include "base/net_multiplayer.h" + +#include "net_unix/udp.h" + +sock_udp_t* newSockUdp(int proto) +{ + sock_udp_t *new; + + new = malloc( sizeof(sock_udp_t) ); + memset(new, 0, sizeof(sock_udp_t)); + new->proto = proto; + + return new; +} + +void destroySockUdp(sock_udp_t *p) +{ + assert( p != NULL ); + free(p); +} + +sock_udp_t* bindUdpSocket(char *address, int port, int proto) +{ + sock_udp_t *new; + int res; + + assert( port > 0 && port < 65535 ); + + new = newSockUdp(proto); + + assert( new != NULL ); + + if( new->proto == PROTO_UDPv4 ) + { + new->sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + } + +#ifdef SUPPORT_IPv6 + if( new->proto == PROTO_UDPv6 ) + { + new->sock = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP); + } +#endif + + if( new->sock < 0 ) + { + fprintf(stderr, "nemozem vytvorit socket !\n"); + destroySockUdp(new); + return NULL; + } + + memset(&(new->sockAddr), 0, sizeof(new->sockAddr)); + + if( new->proto == PROTO_UDPv4 ) + { + new->sockAddr.sin_family = AF_INET; + new->sockAddr.sin_port = htons(port); + new->sockAddr.sin_addr.s_addr = inet_addr(address); + + res = bind(new->sock, (struct sockaddr *)&(new->sockAddr), sizeof(new->sockAddr)); + } + +#ifdef SUPPORT_IPv6 + if( new->proto == PROTO_UDPv6 ) + { + new->sockAddr6.sin6_family = AF_INET6; + new->sockAddr6.sin6_port = htons(port); + inet_pton(AF_INET6, address, &(new->sockAddr6.sin6_addr)); + + res = bind(new->sock, (struct sockaddr *)&(new->sockAddr6), sizeof(new->sockAddr6)); + } +#endif + + if( res < 0 ) + { + fprintf(stderr, "nemozem nastavit sokcet %s %d !\n", address, port); + destroySockUdp(new); + return NULL; + } + + return new; +} + +sock_udp_t* connectUdpSocket(char *address, int port, int proto) +{ + sock_udp_t *new; + + assert( address != NULL ); + assert( port > 0 && port < 65536 ); + + new = newSockUdp(proto); + + assert( new != NULL ); + + if( new->proto == PROTO_UDPv4 ) + { + new->sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + } + +#ifdef SUPPORT_IPv6 + if( new->proto == PROTO_UDPv6 ) + { + new->sock = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP); + } +#endif + + if( new->sock < 0 ) + { + fprintf(stderr, "nemozem vytvorit socket !\n"); + destroySockUdp(new); + return NULL; + } + + memset(&(new->sockAddr), 0, sizeof(new->sockAddr)); + + if( new->proto == PROTO_UDPv4 ) + { + new->sockAddr.sin_family = AF_INET; + new->sockAddr.sin_port = htons(port); + new->sockAddr.sin_addr.s_addr = inet_addr(address); + } + +#ifdef SUPPORT_IPv6 + if( new->proto == PROTO_UDPv6 ) + { + new->sockAddr6.sin6_family = AF_INET6; + new->sockAddr6.sin6_port = htons(port); + inet_pton(AF_INET6, address, &(new->sockAddr6.sin6_addr)); + } +#endif + return new; +} + +int readUdpSocket(sock_udp_t *src, sock_udp_t *dst, void *address, int len) +{ + int addrlen; + int size; + + assert( src != NULL ); + assert( dst != NULL ); + assert( address != NULL ); + + if( dst->proto == PROTO_UDPv4 ) + { + addrlen = sizeof(src->sockAddr); + + size = recvfrom(src->sock, address, len, 0, + (struct sockaddr *)&dst->sockAddr, (socklen_t *)&addrlen); + } + +#ifdef SUPPORT_IPv6 + if( dst->proto == PROTO_UDPv6 ) + { + addrlen = sizeof(src->sockAddr6); + + size = recvfrom(src->sock, address, len, 0, + (struct sockaddr *)&dst->sockAddr6, (socklen_t *)&addrlen); + } +#endif + + if( size < 0 ) + { + char str_ip[STR_IP_SIZE]; + + getSockUdpIp(dst, str_ip, STR_IP_SIZE); + + fprintf(stderr, "nemozem zapisat zo socketu %d %s %d!\n", size, str_ip, getSockUdpPort(dst)); + return -1; + } + + return size; +} + +int writeUdpSocket(sock_udp_t *src, sock_udp_t *dst, void *address, int len) +{ + int addrlen; + int size; + + assert( src != NULL ); + assert( dst != NULL ); + assert( address != NULL ); + + if( dst->proto == PROTO_UDPv4 ) + { + addrlen = sizeof(src->sockAddr); + + size = sendto(src->sock, address, len, 0, + (struct sockaddr *)&dst->sockAddr, (socklen_t)addrlen); + } + +#ifdef SUPPORT_IPv6 + if( dst->proto == PROTO_UDPv6 ) + { + addrlen = sizeof(src->sockAddr6); + + size = sendto(src->sock, address, len, 0, + (struct sockaddr *)&dst->sockAddr6, (socklen_t)addrlen); + } +#endif + + if( size < 0 ) + { + char str_ip[STR_IP_SIZE]; + + getSockUdpIp(dst, str_ip, STR_IP_SIZE); + + fprintf(stderr, "nemozem zapisat na socket %d %s %d!\n", size, str_ip, getSockUdpPort(dst)); + return -1; + } + + return size; +} + +void getSockUdpIp(sock_udp_t *p, char *str_ip, int len) +{ + assert( p != NULL ); + assert( str_ip != NULL ); + + //strcpy(str_ip, inet_ntoa(p->sockAddr.sin_addr)); + + if( p->proto == PROTO_UDPv4 ) + { + inet_ntop(AF_INET, &(p->sockAddr.sin_addr), str_ip, len); + } + +#ifdef SUPPORT_IPv6 + if( p->proto == PROTO_UDPv6 ) + { + inet_ntop(AF_INET6, &(p->sockAddr6.sin6_addr), str_ip, len); + } +#endif +} + +int getSockUdpPort(sock_udp_t *p) +{ + assert( p != NULL ); + + if( p->proto == PROTO_UDPv4 ) + { + return htons(p->sockAddr.sin_port); + } + +#ifdef SUPPORT_IPv6 + if( p->proto == PROTO_UDPv6 ) + { + return htons(p->sockAddr6.sin6_port); + } +#endif + + assert( ! "bad proto !" ); + + return -1; +} + + +void closeUdpSocket(sock_udp_t *p) +{ + assert( p != NULL ); + + close(p->sock); + destroySockUdp(p); +} + +#if 0 + +static int myWait(sock_udp_t *p) +{ + fd_set readfds; + fd_set errorfds; + struct timeval tv; + int max_fd; + + tv.tv_sec = 1; + tv.tv_usec = 0; + + FD_ZERO(&readfds); + FD_ZERO(&errorfds); + max_fd = p->sock; + + FD_SET(p->sock, &readfds); + FD_SET(p->sock, &errorfds); + + select(max_fd+1, &readfds, (fd_set *)0, &errorfds, &tv); + + if( FD_ISSET(p->sock, &readfds) ) + { + FD_CLR(p->sock, &readfds); + return 1; + } + + return 0; +} + +int main(int argc, char *argv[]) +{ + sock_udp_t *sock; + char buf[BUFSIZE]; + int ret; + + if( strcmp(argv[1], "s") == 0 ) + { + sock_udp_t *cli; + + //sock = bindUdpSocket("::1", atoi(argv[2]), PROTO_UDPv6 ); + sock = bindUdpSocket("127.0.0.1", atoi(argv[2]), PROTO_UDPv4 ); + + //cli = newSockUdp(PROTO_UDPv6); + cli = newSockUdp(PROTO_UDPv4); + + while(1) + { + while( myWait(sock) == 0 ) + ; + + memset(buf, 0, BUFSIZE); + ret = readUdpSocket(sock, cli, buf, BUFSIZE); + writeUdpSocket(sock, cli, buf, ret); + } + } + + if( strcmp(argv[1], "c") == 0 ) + { + //sock = connectUdpSocket("::1", atoi(argv[2]), PROTO_UDPv6); + sock = connectUdpSocket("127.0.0.1", atoi(argv[2]), PROTO_UDPv4); + + strcpy(buf, "Hello world !\n"); + writeUdpSocket(sock, sock, buf, strlen(buf)); + + memset(buf, 0, BUFSIZE); + readUdpSocket(sock, sock, buf, BUFSIZE); + + printf("buf = %s", buf); + //while(1)sleep(1); + closeUdpSocket(sock); + } + + return 0; +} +#endif + |