Skip to content

Instantly share code, notes, and snippets.

@avelican
Created January 29, 2024 17:10
Show Gist options
  • Save avelican/7fd79e57989db30761b7bf323787d334 to your computer and use it in GitHub Desktop.
Save avelican/7fd79e57989db30761b7bf323787d334 to your computer and use it in GitHub Desktop.
Noob's attempt: Cross Platform UDP (Linux + Windows)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN // prevent import of WinSock ? (conflict with WinSock2)
#include <windows.h> // sleep()
#define sleep(n) Sleep((n) * 1000)
#include <winsock2.h>
#include <ws2tcpip.h>
# define close closesocket
#else
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h> // sleep()
#endif
void main(int argc, char **argv){
if(argc != 2){
printf("Usage: %s <port>\n", argv[0]);
exit(0);
}
#ifdef _WIN32
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
fprintf(stderr, "WSAStartup failed.\n");
exit(1);
}
if (LOBYTE(wsaData.wVersion) != 2 ||
HIBYTE(wsaData.wVersion) != 2)
{
fprintf(stderr,"Version 2.2 of Winsock is not available.\n");
WSACleanup();
exit(2);
}
#endif
int port = atoi(argv[1]);
int sockfd;
struct sockaddr_in serverAddr;
char buffer[1024];
socklen_t addr_size;
sockfd = socket(PF_INET, SOCK_DGRAM, 0);
memset(&serverAddr, '\0', sizeof(serverAddr));
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(port);
serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
strcpy(buffer, "Hello Server\n");
while(1){
// sendto(sockfd, buffer, 1024, 0, (struct sockaddr*)&serverAddr, sizeof(serverAddr));
sendto(sockfd, buffer, 1024, 0, (struct sockaddr*)&serverAddr, sizeof(serverAddr));
printf("[+]Data Send: %s", buffer);
sleep(1);
}
close(sockfd);
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#ifdef _WIN32
# define WIN32_LEAN_AND_MEAN
# include <windows.h>
# define sleep(n) Sleep((n) * 1000)
# include <winsock2.h>
# include <ws2tcpip.h>
# define close closesocket
#else
# include <sys/socket.h>
# include <netinet/in.h>
# include <arpa/inet.h>
# include <unistd.h> // sleep()
#endif
void net_init() {
printf("Server starting.\n");
#ifdef _WIN32
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
fprintf(stderr, "WSAStartup failed.\n");
exit(1);
}
if (LOBYTE(wsaData.wVersion) != 2 ||
HIBYTE(wsaData.wVersion) != 2)
{
fprintf(stderr,"Version 2.2 of Winsock is not available.\n");
WSACleanup();
exit(2);
}
#endif
}
void net_exit() {
#ifdef _WIN32
WSACleanup();
#endif
}
void main(int argc, char **argv){
// if(argc != 2){
// printf("Usage: %s <port>\n", argv[0]);
// exit(0);
// }
char* address = "127.0.0.1";
char* port_str = "1111";
net_init();
// int port = atoi(argv[1]);
int port = atoi(port_str);
// TODO: make global; move to net_init()?
int sockfd;
struct sockaddr_in si_me, si_other;
char buffer[1024]; // TODO: how to queue messages in and out?
socklen_t addr_size;
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
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 = inet_addr("127.0.0.1");
// inet_aton("127.0.0.1", si_me.sin_addr); // doesn't work on windows.. sigh
inet_pton(AF_INET, address, &si_me.sin_addr.s_addr);
// NOTE: Can also use AF_INET6
// https://stackoverflow.com/questions/23187496/what-is-the-meaning-of-sin-addr-s-addr-and-inet-addr
// inet_addr was deprecated in favour of inet_aton even before IPv6 come into play because it's a poorly designed API call. It signals an error by returning INADDR_NONE (-1) but its return type in_addr_t is actually an unsigned integer, which makes passing the signed -1 very compiler-dependent. Also on machines with two's complement representation of negative numbers (that's most computer architectures nowadays) INADDR_NONE equals INADDR_BROADCAST (255.255.255.255).
///////////
// kept becaue funny
// int bindstatus = bind(sockfd, (struct sockaddr*)&si_me, sizeof(si_me));
// if (bindstatus !=0 ) {
// #ifdef _WIN32 // sigh
// int WS_err = WSAGetLastError();
// if (WS_err == WSAEADDRINUSE) {
// #else
// if (errno == EADDRINUSE) {
// #endif
// // for local usage. If port used, try next port
// printf("port %d taken... trying %d", port, port+1);
// port++;
// si_me.sin_port = htons(port);
// int bindstatus2 = bind(sockfd, (struct sockaddr*)&si_me, sizeof(si_me));
// if (bindstatus2 != 0) {
// #ifdef _WIN32
// int WS_err = WSAGetLastError(); // note: shadowed in nested block
// printf("Could not bind to port. WS_err: %d", WS_err);
// #else
// printf("Could not bind to port. errno: %d", errno);
// #endif
// exit(1);
// }
// } else {
// #ifdef _WIN32
// int WS_err = WSAGetLastError(); // note: shadowed in nested block
// printf("Could not bind to port. WS_err: %d", WS_err);
// #else
// printf("Could not bind to port. errno: %d", errno);
// #endif
// exit(1);
// }
// }
#ifdef _WIN32
int bindstatus = bind(sockfd, (struct sockaddr*)&si_me, sizeof(si_me));
if (bindstatus !=0 ) {
int WS_err = WSAGetLastError();
if (WS_err == WSAEADDRINUSE) {
// for local usage. If port used, try next port
printf("port %d taken... trying %d", port, port+1);
port++;
si_me.sin_port = htons(port);
int bindstatus2 = bind(sockfd, (struct sockaddr*)&si_me, sizeof(si_me));
if (bindstatus2 != 0) {
int WS_err = WSAGetLastError(); // note: shadowed in nested block
printf("Could not bind to port. WS_err: %d", WS_err);
exit(1);
}
} else {
int WS_err = WSAGetLastError(); // note: shadowed in nested block
printf("Could not bind to port. WS_err: %d", WS_err);
exit(1);
}
}
#else
int bindstatus = bind(sockfd, (struct sockaddr*)&si_me, sizeof(si_me));
if (bindstatus !=0 ) {
if (errno == EADDRINUSE) {
// for local usage. If port used, try next port
printf("port %d taken... trying %d", port, port+1);
port++;
si_me.sin_port = htons(port);
int bindstatus2 = bind(sockfd, (struct sockaddr*)&si_me, sizeof(si_me));
if (bindstatus2 != 0) {
printf("Could not bind to port. errno: %d", errno);
exit(1);
}
} else {
printf("Could not bind to port. errno: %d", errno);
exit(1);
}
}
#endif
addr_size = sizeof(si_other);
printf("Server started. Listening on %s:%d", address, port);
while(1){
int recvstat = recvfrom(sockfd, buffer, 1024, 0, (struct sockaddr*)(struct sockaddr*)& si_other, &addr_size);
if (recvstat < 0)
{
printf("*** ERROR - recvfrom() failed \n");
exit(-1);
} else {
printf("[+]Data Received: %s", buffer);
printf(" FROM: %s:%d", inet_ntoa(si_other.sin_addr), si_other.sin_port);
}
}
close(sockfd);
net_exit();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment