Skip to content

Instantly share code, notes, and snippets.

@jubnzv

jubnzv/Makefile Secret

Created February 18, 2021 11:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jubnzv/93d7f1f3e334552fcb6cd01aedfee93b to your computer and use it in GitHub Desktop.
Save jubnzv/93d7f1f3e334552fcb6cd01aedfee93b to your computer and use it in GitHub Desktop.
#include <arpa/inet.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include "network-api.h"
int main()
{
int fd;
if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
perror("socket");
exit(EXIT_FAILURE);
}
struct sockaddr_in addr;
addr.sin_addr.s_addr = inet_addr("127.0.0.1");
addr.sin_port = htons(9000);
addr.sin_family = AF_INET;
if (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) != 0) {
perror("connect");
exit(EXIT_FAILURE);
}
int attempts_left = 5;
while (--attempts_left > 0) {
char in_data[6];
char *out_data = "test\0";
printf("send\n");
if (blocking_send(fd, out_data, 6) != 0)
break;
printf("recv\n");
if (blocking_recv(fd, in_data, 6) != 0)
break;
printf("done (attempts left: %d)\n", attempts_left);
sleep(1);
}
printf("Closing socket\n");
close(fd);
return 0;
}
all:
gcc server.c network-api.c -o server
gcc client.c network-api.c -o client
#include <arpa/inet.h>
#include <stdio.h>
#include "network-api.h"
int blocking_recv(int sock, char *data, size_t size) {
size_t remain_data = size;
ssize_t recv_nb;
int offset = 0;
while ((remain_data > 0) &&
((recv_nb = recv(sock, data + offset, remain_data, 0)) >= 0)) {
remain_data -= recv_nb;
offset += recv_nb;
}
if (recv_nb == -1 || remain_data > 0) {
perror("recv");
return -1;
}
return 0;
}
int blocking_send(int sock, char *buf, size_t size) {
size_t total = 0;
int remain = size;
int n;
while (total < size) {
n = send(sock, buf + total, remain, 0);
if (n == -1) {
perror("send");
break;
}
total += n;
remain -= n;
}
return (total == size) ? 0 : -1;
}
int set_timeout(int fd, int sec) {
struct timeval timeout;
timeout.tv_sec = sec;
timeout.tv_usec = 0;
if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout,
sizeof(timeout)) < 0) {
perror("setsockopt");
return -1;
}
if (setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout,
sizeof(timeout)) < 0) {
perror("setsockopt");
return -1;
}
return 0;
}
#ifndef NETWORK_API_H
#define NETWORK_API_H
#include <stddef.h>
int blocking_recv(int sock, char *data, size_t size);
int blocking_send(int sock, char *buf, size_t size);
int set_timeout(int fd, int sec);
#endif // NETWORK_API_H
#include <arpa/inet.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "network-api.h"
static const int data_size = 6;
int main() {
int server_fd;
int client_fd;
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
perror("socket");
exit(EXIT_FAILURE);
}
int v = 1;
setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &v, sizeof(v));
struct sockaddr_in saddr;
memset(&saddr, 0, sizeof(saddr));
saddr.sin_family = AF_INET;
saddr.sin_addr.s_addr = INADDR_ANY;
saddr.sin_port = htons(9000);
if (bind(server_fd, (struct sockaddr *)&saddr, sizeof(saddr)) != 0) {
perror("bind");
exit(EXIT_FAILURE);
}
if (listen(server_fd, 10) != 0) {
perror("listen");
exit(EXIT_FAILURE);
}
while (1) {
struct sockaddr_in caddr;
size_t len = sizeof(caddr);
printf("Waiting for connection\n");
if ((client_fd = accept(server_fd, (struct sockaddr *)&caddr, (socklen_t *)&len)) < 0) {
perror("accept");
continue;
}
printf("Connection accepted\n");
// Set the timeout using SO_{SND,RCV}TIMEO
if (set_timeout(client_fd, 3) != 0) {
continue;
}
// Send and receive data in the loop. We assume that the client is stuck,
// we'll break the connection using a timeout.
while (1) {
char in_data[data_size];
char *out_data = "test\0";
printf("recv\n");
if (blocking_recv(client_fd, in_data, data_size) != 0)
break;
printf("send\n");
if (blocking_send(client_fd, out_data, data_size) != 0)
break;
printf("done\n");
}
printf("Waiting for new connection.\n");
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment