Last active
April 30, 2025 22:22
-
-
Save meowstr/ac874701f1cff1a0621567686478a94c to your computer and use it in GitHub Desktop.
posix udp poll based example
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
| #include <arpa/inet.h> | |
| #include <sys/poll.h> | |
| #include <sys/socket.h> | |
| #include <stdio.h> | |
| #include <string.h> | |
| #include <unistd.h> | |
| static struct { | |
| sockaddr local; | |
| int socket; | |
| sockaddr * remote_list; | |
| int remote_count; | |
| } intern; | |
| int init_net( int port ) | |
| { | |
| int ret; | |
| intern.remote_list = new sockaddr[ 32 ]; | |
| static sockaddr_in addr; | |
| addr.sin_family = AF_INET; | |
| addr.sin_port = htons( port ); | |
| addr.sin_addr.s_addr = htonl( INADDR_ANY ); | |
| memcpy( &intern.local, &addr, sizeof( sockaddr_in ) ); | |
| intern.socket = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP ); | |
| if ( intern.socket == -1 ) { | |
| fprintf( stderr, "socket() failed\n" ); | |
| return 1; | |
| } | |
| ret = bind( intern.socket, &intern.local, sizeof( sockaddr ) ); | |
| if ( ret == -1 ) { | |
| fprintf( stderr, "bind() failed\n" ); | |
| return 1; | |
| } | |
| return 0; | |
| } | |
| int add_net_remote( const char * ip, int port ) | |
| { | |
| static sockaddr_in addr; | |
| addr.sin_family = AF_INET; | |
| addr.sin_port = htons( port ); | |
| addr.sin_addr.s_addr = inet_addr( ip ); | |
| int id = intern.remote_count++; | |
| memcpy( intern.remote_list + id, &addr, sizeof( sockaddr_in ) ); | |
| return id; | |
| } | |
| void terminate_net() | |
| { | |
| close( intern.socket ); | |
| } | |
| int poll_packet( char * buffer, int size, int * source ) | |
| { | |
| pollfd info; | |
| info.fd = intern.socket; | |
| info.events = POLLIN; | |
| int ret = poll( &info, 1, 0 ); | |
| if ( ret == -1 ) { | |
| fprintf( stderr, "poll() failed\n" ); | |
| return -1; | |
| } | |
| if ( ret == 0 ) { | |
| // no events | |
| return 0; | |
| } | |
| socklen_t addr_len = sizeof( sockaddr ); | |
| sockaddr addr; | |
| int len = recvfrom( intern.socket, buffer, size, 0, &addr, &addr_len ); | |
| // find remote | |
| for ( int i = 0; i < intern.remote_count; i++ ) { | |
| if ( memcmp( &addr, intern.remote_list + i, sizeof( sockaddr ) ) == | |
| 0 ) { | |
| *source = i; | |
| return len; | |
| } | |
| } | |
| // new remote | |
| int id = intern.remote_count++; | |
| memcpy( intern.remote_list + id, &addr, sizeof( sockaddr ) ); | |
| *source = id; | |
| return len; | |
| } | |
| int send_packet( int dest, const void * buffer, int size ) | |
| { | |
| int ret = sendto( | |
| intern.socket, | |
| buffer, | |
| size, | |
| 0, | |
| intern.remote_list + dest, | |
| sizeof( sockaddr ) | |
| ); | |
| if ( ret == -1 ) { | |
| fprintf( stderr, "sendto() failed\n" ); | |
| } | |
| return ret; | |
| } |
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
| #pragma once | |
| /// @param port | |
| /// @return 0 on success | |
| int init_net( int port ); | |
| void terminate_net(); | |
| /// @param ip | |
| /// @param port | |
| /// @return remote id | |
| int add_net_remote( const char * ip, int port ); | |
| /// @param buffer | |
| /// @param size | |
| /// @param source remote id of the packet's source | |
| /// @return bytes recieved | |
| int poll_packet( char * buffer, int size, int * source ); | |
| /// @param dest remote id of packet's destination | |
| /// @param buffer | |
| /// @param size | |
| /// @return bytes sent | |
| int send_packet( int dest, const void * buffer, int size ); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment