Skip to content

Instantly share code, notes, and snippets.

@techiepriyansh
Last active February 2, 2022 13:09
Show Gist options
  • Save techiepriyansh/b12e8f3554c227c196f5975789ddeb75 to your computer and use it in GitHub Desktop.
Save techiepriyansh/b12e8f3554c227c196f5975789ddeb75 to your computer and use it in GitHub Desktop.
Simple TCP Socket Server and Client in C
#ifndef INCLUDE_ERR_CHECK_H
#define INCLUDE_ERR_CHECK_H
#define ERR_CHECK(x, y) do { \
int retval = (x); \
if (retval == -1) { \
perror((y)); \
exit(1); \
} \
} while(0)
#define ERR_CHECK_RET(x, y, z) do { \
int retval = (x); \
if (retval == -1) { \
perror((z)); \
exit(1); \
} else { \
*(y) = retval; \
} \
} while(0)
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include "err_check.h"
#define CHUNK_LEN 256
int main(int argc, char *argv[])
{
struct addrinfo hints, *res;
int sockfd, status;
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
if ((status = getaddrinfo(argv[1], argv[2], &hints, &res)) != 0) {
fprintf(stderr, "getaddrinfo error: %s\n", gai_strerror(status));
exit(1);
}
ERR_CHECK_RET(socket(res->ai_family, res->ai_socktype, res->ai_protocol), &sockfd, "socket");
ERR_CHECK(connect(sockfd, res->ai_addr, res->ai_addrlen), "connect");
char buf[CHUNK_LEN];
int bytes_read;
memset(buf, 0, CHUNK_LEN);
ERR_CHECK_RET(recv(sockfd, buf, CHUNK_LEN, 0), &bytes_read, "recv");
printf("%d bytes read\n", bytes_read);
printf("%s", buf);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include "err_check.h"
#define DEFAULT_PORT "3490"
#define LISTEN_QUEUE_CAPACITY 5
int main(int argc, char *argv[])
{
struct sockaddr_storage client_addr;
socklen_t client_addr_size;
struct addrinfo hints, *res;
int sockfd, client_sockfd, status;
bool using_custom_host = argc == 3;
char* hostname = using_custom_host ? argv[1] : NULL;
char* port = using_custom_host ? argv[2] : DEFAULT_PORT;
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
if (!using_custom_host) hints.ai_flags = AI_PASSIVE;
if ((status = getaddrinfo(hostname, port, &hints, &res)) != 0) {
fprintf(stderr, "getaddrinfo error: %s\n", gai_strerror(status));
exit(1);
};
ERR_CHECK_RET(socket(res->ai_family, res->ai_socktype, res->ai_protocol), &sockfd, "socket");
int yes = 1;
ERR_CHECK(setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof yes), "setsockopt");
ERR_CHECK(bind(sockfd, res->ai_addr, res->ai_addrlen), "bind");
ERR_CHECK(listen(sockfd, LISTEN_QUEUE_CAPACITY), "listen");
client_addr_size = sizeof client_addr_size;
ERR_CHECK_RET(accept(sockfd, (struct sockaddr *)&client_addr, &client_addr_size), &client_sockfd, "accept");
char *msg = "Santa was here!\n";
int len, bytes_sent;
len = strlen(msg);
ERR_CHECK_RET(send(client_sockfd, msg, len, 0), &bytes_sent, "send");
printf("%d bytes sent\n", bytes_sent);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment