-
-
Save madgarden/5453726 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// LICENSE | |
// | |
// This software is dual-licensed to the public domain and under the following | |
// license: you are granted a perpetual, irrevocable license to copy, modify, | |
// publish, and distribute this file as you see fit. | |
#include "udpnet.h" | |
#if defined WIN32 | |
typedef int socklen_t; | |
#else | |
#define closesocket(s) close(s) | |
#endif | |
static int udp_err_ = 0; | |
int udp_error(void) | |
{ | |
return udp_err_; | |
} | |
void udp_socket_init(void) | |
{ | |
#if defined WIN32 | |
WSADATA wsa_data; | |
WSAStartup(MAKEWORD(1,1), &wsa_data); | |
#endif | |
} | |
void udp_socket_exit(void) | |
{ | |
#if defined WIN32 | |
WSACleanup(); | |
#endif | |
} | |
int udp_create_endpoint(int port) | |
{ | |
struct sockaddr_in si_me; | |
int s; | |
const struct sockaddr *me; | |
s = socket(AF_INET, SOCK_DGRAM|SOCK_NONBLOCK, IPPROTO_UDP); | |
if(s < 0) | |
{ | |
udp_err_ = errno; | |
return s; | |
} | |
if(port) | |
{ | |
int ret; | |
memset(&si_me, 0, sizeof(si_me)); | |
si_me.sin_family = AF_INET; | |
si_me.sin_port = htons(port); | |
si_me.sin_addr.s_addr = htonl(INADDR_ANY); | |
me = (const struct sockaddr*)&si_me; | |
ret = bind(s, me, sizeof(si_me)); | |
if(ret < 0) | |
{ | |
udp_err_ = errno; | |
return ret; | |
} | |
} | |
udp_err_ = 0; | |
return s; | |
} | |
int udp_close_endpoint(int s) | |
{ | |
int ret = closesocket(s); | |
udp_err_ = errno; | |
return ret; | |
} | |
int udp_receive(int s, void *data, int size, UDPNET_ADDRESS *src) | |
{ | |
struct sockaddr_in si_other; | |
socklen_t slen = sizeof(si_other); | |
struct sockaddr *sender = NULL; | |
int ret; | |
if(src) | |
{ | |
sender = (struct sockaddr*)&si_other; | |
} | |
ret = recvfrom(s, data, size, MSG_DONTWAIT, sender, &slen); | |
udp_err_ = errno; | |
if(ret < 0) | |
{ | |
return ret; | |
} | |
if(src) | |
{ | |
src->port = ntohs(si_other.sin_port); | |
strcpy(src->address, inet_ntoa(si_other.sin_addr)); | |
} | |
return ret; | |
} | |
int udp_send(int s, void *data, int size, const char *address, | |
int port) | |
{ | |
struct sockaddr_in theiraddr; | |
int lenaddr = sizeof(theiraddr); | |
struct sockaddr *receiver; | |
if(!address) return -1; | |
memset(&theiraddr, 0, lenaddr); | |
theiraddr.sin_family = AF_INET; | |
theiraddr.sin_port = htons(port); | |
receiver = (struct sockaddr *)&theiraddr; | |
if(inet_aton(address, &theiraddr.sin_addr) == 0) | |
{ | |
udp_err_ = errno; | |
return -1; | |
} | |
if(sendto(s, data, size, MSG_DONTWAIT, receiver, lenaddr) < 0) | |
{ | |
udp_err_ = errno; | |
return -2; | |
} | |
udp_err_ = errno; | |
return 0; | |
} | |
/* | |
#define LOCAL_IP "127.0.0.1" | |
#define BUFLEN 512 | |
#define NPACK 10 | |
#define SERVER_PORT 9001 | |
#define CLIENT_PORT 9002 | |
int client_test(SOCKET s) | |
{ | |
char buf[BUFLEN]; | |
int i; | |
for(i = 0; i < NPACK; i++) | |
{ | |
sprintf(buf, "This is SPARTA!!!!! %d", i); | |
if(udp_send(s, buf, BUFLEN, LOCAL_IP, SERVER_PORT) < 0) | |
{ | |
perror("udp_send:\n"); | |
break; | |
} | |
} | |
close(s); | |
return 1; | |
} | |
int server_test(SOCKET s) | |
{ | |
int i; | |
char buf[BUFLEN]; | |
UDPNET_ADDRESS addr; | |
i = 0; | |
while(i < NPACK) | |
{ | |
int ret = udp_receive(s, buf, BUFLEN, &addr); | |
if(ret < 0) | |
{ | |
if(udp_error() == EWOULDBLOCK) | |
{ | |
continue; | |
} | |
else if(udp_error() == EAGAIN) | |
{ | |
continue; | |
} | |
else | |
{ | |
return -1; | |
} | |
} | |
printf("Received %d bytes from %s:%d\n", | |
ret, | |
addr.address, | |
addr.port); | |
printf("DATA: %s\n", buf); | |
i++; | |
} | |
return 0; | |
} | |
static void error_out(const char *str) | |
{ | |
perror(str); | |
exit(1); | |
} | |
int main(void) | |
{ | |
SOCKET server, client; | |
udp_socket_init(); | |
server = udp_create_endpoint(SERVER_PORT); | |
if(server < 0) error_out("socket"); | |
client = udp_create_endpoint(0); | |
if(client < 0) error_out("socket"); | |
client_test(client); | |
server_test(server); | |
udp_close_endpoint(client); | |
udp_close_endpoint(server); | |
udp_socket_exit(); | |
} | |
*/ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Hacked up one day in March 2013, by Madgarden | |
// LICENSE | |
// | |
// This software is dual-licensed to the public domain and under the following | |
// license: you are granted a perpetual, irrevocable license to copy, modify, | |
// publish, and distribute this file as you see fit. | |
#ifndef __UDPNET_H__ | |
#define __UDPNET_H__ | |
#include <errno.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#if defined WIN32 | |
#include <winsock.h> | |
#else | |
#include <unistd.h> | |
#include <netdb.h> | |
#include <sys/types.h> | |
#include <sys/socket.h> | |
#include <arpa/inet.h> | |
#endif | |
typedef struct | |
{ | |
int port; | |
char address[20]; | |
}UDPNET_ADDRESS; | |
void udp_socket_init(void); | |
void udp_socket_exit(void); | |
int udp_create_endpoint(int port); | |
int udp_close_endpoint(int s); | |
int udp_send(int s, void *data, int size, const char *address, | |
int port); | |
int udp_receive(int s, void *data, int size, UDPNET_ADDRESS *src); | |
int udp_error(void); | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment