tangled
alpha
login
or
join now
stau.space
/
enchufe
0
fork
atom
Librería para enchufes en C.
0
fork
atom
overview
issues
pulls
pipelines
feat: Changed project to enchufe name
stau.space
6 months ago
ef7c4aa8
17bac48c
+223
-153
12 changed files
expand all
collapse all
unified
split
Makefile
src
client.c
lib
enchufe.c
enchufe.h
log.c
log.h
log.c
log.h
server.c
socket.c
socket.h
utils.h
+3
-3
Makefile
···
1
1
-
LIB=src/socket.c src/log.c
2
2
-
CFLAGS=-g
1
1
+
LIB=src/lib/log.c src/lib/enchufe.c
2
2
+
CFLAGS=-g -lpthread
3
3
4
4
.build/server:
5
5
-
gcc $(GFLAGS) -o .build/server src/server.c $(LIB)
5
5
+
gcc $(CFLAGS) -o .build/server src/server.c $(LIB)
6
6
7
7
run-server: .build/server
8
8
./.build/server
+28
-33
src/client.c
···
1
1
-
#include "log.h"
2
2
-
#include "socket.h"
3
3
-
#include "utils.h"
4
1
#include <stdio.h>
5
2
#include <unistd.h>
6
6
-
#include <arpa/inet.h>
7
7
-
3
3
+
#include "lib/enchufe.h"
4
4
+
#include "lib/log.h"
5
5
+
#define BUF_LEN 0x100
8
6
9
7
int main() {
10
10
-
int sock = socket(PF_INET, SOCK_STREAM, 0);
11
11
-
try (sock);
12
12
-
log_info("Created socket.");
13
13
-
14
14
-
struct sockaddr_in server_addr = {
15
15
-
.sin_family = AF_INET,
16
16
-
.sin_port = htons(42069),
8
8
+
EnchufeFD fd = enchufa();
9
9
+
Receptaculo rec = receptaculo((IPv4){127,0,0,1}, 42069);
10
10
+
Enchufe enchufe = {
11
11
+
.fd = fd,
12
12
+
.addr = rec.addr,
13
13
+
.addrlen = rec.addrlen,
17
14
};
15
15
+
log_info("Got socket: %d\n", enchufe.fd);
18
16
19
19
-
try (inet_pton(AF_INET, "100.96.176.98", &server_addr.sin_addr));
17
17
+
log_info("Connecting to socket.\n");
18
18
+
conecta(enchufe);
20
19
20
20
+
char in_buf[BUF_LEN] = {0};
21
21
+
char out_buf[BUF_LEN] = {0};
21
22
22
22
-
try (connect(sock, (const struct sockaddr*)&server_addr, sizeof(server_addr)));
23
23
-
log_info("Connected socket to server.");
24
24
-
25
25
-
/*
26
26
-
* Time to write :3
27
27
-
*/
28
28
-
char buf[0x1000] = {0};
29
29
-
char msg[0x100] = {0};
30
30
-
31
31
-
try (read(sock, buf, 0x1000 - 1));
32
32
-
printf("[INFO]: Received a message.\n%s\n", buf);
23
23
+
log_info("Reading from socket.\n");
24
24
+
recibe(enchufe, in_buf, BUF_LEN - 1);
25
25
+
log_info("Received a message: %s", in_buf);
26
26
+
memset(in_buf, 0, BUF_LEN);
33
27
34
28
while (1) {
35
35
-
printf("[INFO]: Sending message:\n>\t");
36
36
-
fgets(msg, 0x100 - 1, stdin);
37
37
-
msg[strlen(msg) - 1] = '\0';
38
38
-
send(sock, msg, strlen(msg), 0);
29
29
+
log_info("Sending message: ");
39
30
40
40
-
size_t len = read(sock, buf, 0x1000 - 1);
41
41
-
try (len);
42
42
-
buf[len] = '\0';
43
43
-
printf("[INFO]: Received a message:\n>\t%s\n", buf);
31
31
+
char *rec = fgets(out_buf, BUF_LEN - 1, stdin);
32
32
+
if (rec == NULL) try(-1);
33
33
+
zumba(enchufe, out_buf);
34
34
+
memset(out_buf, 0, BUF_LEN);
35
35
+
36
36
+
recibe(enchufe, in_buf, BUF_LEN - 1);
37
37
+
log_info("Received a message: %s", in_buf);
38
38
+
memset(in_buf, 0, BUF_LEN);
44
39
}
45
40
46
46
-
close(sock);
41
41
+
desenchufa(enchufe);
47
42
return 0;
48
43
}
+73
src/lib/enchufe.c
···
1
1
+
#include "enchufe.h"
2
2
+
#include <unistd.h>
3
3
+
#include <stdint.h>
4
4
+
#include <sys/socket.h> // all the socket functions
5
5
+
#include <netinet/in.h> // sockaddr_in
6
6
+
#include <arpa/inet.h> // inet_pton
7
7
+
8
8
+
9
9
+
10
10
+
EnchufeFD enchufa() {
11
11
+
int sockfd = socket(PF_INET, SOCK_STREAM, 0);
12
12
+
try (sockfd);
13
13
+
return sockfd;
14
14
+
}
15
15
+
16
16
+
Enchufe amarra(EnchufeFD fd, IPv4 ip, uint16_t port) {
17
17
+
struct sockaddr_in name = {
18
18
+
.sin_family = AF_INET,
19
19
+
.sin_addr = ip.ip,
20
20
+
.sin_port = htons(port),
21
21
+
};
22
22
+
23
23
+
Enchufe enchufe = {
24
24
+
.fd = fd,
25
25
+
.addr = name,
26
26
+
.addrlen = sizeof(name),
27
27
+
};
28
28
+
29
29
+
try (bind(enchufe.fd, (struct sockaddr*)&enchufe.addr, enchufe.addrlen));
30
30
+
return enchufe;
31
31
+
}
32
32
+
33
33
+
Enchufe acepta(Enchufe enchufe) {
34
34
+
EnchufeFD fd = accept(enchufe.fd, (struct sockaddr*)&enchufe.addr, &enchufe.addrlen);
35
35
+
try (fd);
36
36
+
return (Enchufe){
37
37
+
.fd = fd,
38
38
+
.addr = enchufe.addr,
39
39
+
.addrlen = enchufe.addrlen,
40
40
+
};
41
41
+
}
42
42
+
43
43
+
void zumba(Enchufe enchufe, const char* msg) {
44
44
+
send(enchufe.fd, msg, strlen(msg), 0);
45
45
+
}
46
46
+
47
47
+
void escucha(Enchufe enchufe, size_t len) {
48
48
+
listen(enchufe.fd, len);
49
49
+
}
50
50
+
51
51
+
void desenchufa(Enchufe enchufe) {
52
52
+
close(enchufe.fd);
53
53
+
}
54
54
+
55
55
+
void recibe(Enchufe enchufe, char* buf, size_t nbytes) {
56
56
+
try (read(enchufe.fd, buf, nbytes));
57
57
+
}
58
58
+
59
59
+
void conecta(Enchufe enchufe) {
60
60
+
try (connect(enchufe.fd, (const struct sockaddr*)&enchufe.addr, enchufe.addrlen));
61
61
+
}
62
62
+
63
63
+
Receptaculo receptaculo(IPv4 ip, uint16_t port) {
64
64
+
struct sockaddr_in name = {
65
65
+
.sin_family = AF_INET,
66
66
+
.sin_addr = ip.ip,
67
67
+
.sin_port = htons(port),
68
68
+
};
69
69
+
return (Receptaculo){
70
70
+
.addr = name,
71
71
+
.addrlen = sizeof(name),
72
72
+
};
73
73
+
}
+46
src/lib/enchufe.h
···
1
1
+
#ifndef ENCHUFE_H_
2
2
+
#define ENCHUFE_H_
3
3
+
#include <errno.h>
4
4
+
#include <netinet/in.h>
5
5
+
#include <stdint.h>
6
6
+
#include <stdio.h>
7
7
+
#include <stdlib.h>
8
8
+
#include <string.h>
9
9
+
#include <sys/socket.h>
10
10
+
11
11
+
#define try(a) do { \
12
12
+
if ((a) < 0) { \
13
13
+
fprintf(stderr, "[ERROR]: %s:%d In function %s: %s\n", __FILE__, __LINE__, __FUNCTION__, strerror(errno)); \
14
14
+
exit (EXIT_FAILURE); \
15
15
+
} \
16
16
+
} while(0)
17
17
+
18
18
+
typedef int EnchufeFD;
19
19
+
20
20
+
typedef union {
21
21
+
uint8_t bytes[4];
22
22
+
uint32_t ip;
23
23
+
} IPv4;
24
24
+
25
25
+
typedef struct {
26
26
+
EnchufeFD fd;
27
27
+
struct sockaddr_in addr;
28
28
+
socklen_t addrlen;
29
29
+
} Enchufe;
30
30
+
31
31
+
typedef struct {
32
32
+
struct sockaddr_in addr;
33
33
+
socklen_t addrlen;
34
34
+
} Receptaculo;
35
35
+
36
36
+
EnchufeFD enchufa();
37
37
+
Enchufe amarra(EnchufeFD fd, IPv4 ip, uint16_t port);
38
38
+
Enchufe acepta(Enchufe enchufe);
39
39
+
void zumba(Enchufe enchufe, const char* msg);
40
40
+
void escucha(Enchufe enchufe, size_t len);
41
41
+
void desenchufa(Enchufe enchufe);
42
42
+
void recibe(Enchufe enchufe, char* buf, size_t nbytes);
43
43
+
void conecta(Enchufe enchufe);
44
44
+
Receptaculo receptaculo(IPv4 ip, uint16_t port);
45
45
+
46
46
+
#endif // ENCHUFE_H_ header
+29
src/lib/log.c
···
1
1
+
#include <stdio.h>
2
2
+
#include <stdarg.h>
3
3
+
4
4
+
void log_info(const char* format, ...) {
5
5
+
printf("[INFO]: ");
6
6
+
7
7
+
va_list list;
8
8
+
va_start(list, format);
9
9
+
vprintf(format, list);
10
10
+
va_end(list);
11
11
+
}
12
12
+
13
13
+
void log_error(const char* format, ...) {
14
14
+
fprintf(stderr, "[ERROR]: ");
15
15
+
16
16
+
va_list list;
17
17
+
va_start(list, format);
18
18
+
vfprintf(stderr, format, list);
19
19
+
va_end(list);
20
20
+
}
21
21
+
22
22
+
void log_warn(const char* format, ...) {
23
23
+
printf("[WARN]: ");
24
24
+
25
25
+
va_list list;
26
26
+
va_start(list, format);
27
27
+
vprintf(format, list);
28
28
+
va_end(list);
29
29
+
}
+7
src/lib/log.h
···
1
1
+
#ifndef LOG_H_
2
2
+
#define LOG_H_
3
3
+
4
4
+
void log_info(const char* format, ...);
5
5
+
void log_error(const char* format, ...);
6
6
+
void log_WARN(const char* format, ...);
7
7
+
#endif // LOG_H_ header
-5
src/log.c
···
1
1
-
#include <stdio.h>
2
2
-
3
3
-
void log_info(const char* str) { printf("[INFO]: %s\n", str); }
4
4
-
void log_error(const char* str) { printf("[ERROR]: %s\n", str); }
5
5
-
void log_WARN(const char* str) { printf("[WARN]: %s\n", str); }
-7
src/log.h
···
1
1
-
#ifndef LOG_H_
2
2
-
#define LOG_H_
3
3
-
4
4
-
void log_info(const char* str);
5
5
-
void log_error(const char* str);
6
6
-
void log_WARN(const char* str);
7
7
-
#endif // LOG_H_ header
+37
-38
src/server.c
···
1
1
-
#include "log.h"
2
2
-
#include "socket.h"
3
3
-
#include "utils.h"
4
4
-
#include <unistd.h>
1
1
+
#include "lib/log.h"
2
2
+
#include "lib/enchufe.h"
3
3
+
#include <pthread.h>
4
4
+
#define BUF_LEN 0x100
5
5
+
#define THREAD_COUNT 5
5
6
7
7
+
void* echo(void* args) {
8
8
+
if (args != NULL) {
9
9
+
Enchufe enchufe = *(Enchufe*)args;
10
10
+
Enchufe cliente = acepta(enchufe);
11
11
+
log_info("Accepted client: %d\n", cliente.fd);
6
12
7
7
-
int main() {
8
8
-
int sock = socket(PF_INET, SOCK_STREAM, 0);
13
13
+
char msg[] = "[ECHO]: You have succesfully connected to the echo server.\n";
14
14
+
log_info("Sending message: %s", msg);
15
15
+
zumba(cliente, msg);
9
16
10
10
-
struct sockaddr_in name = {
11
11
-
.sin_family = AF_INET,
12
12
-
.sin_addr.s_addr = htonl(INADDR_LOOPBACK),
13
13
-
.sin_port = htons(42069),
14
14
-
};
15
15
-
socklen_t addrlen = sizeof(name);
17
17
+
char buf[BUF_LEN] = {0};
18
18
+
while (1) {
19
19
+
recibe(cliente, buf, BUF_LEN - 1);
20
20
+
log_info("Read message: %s", buf);
21
21
+
log_info("Sending message: %s", buf);
22
22
+
zumba(cliente, buf);
23
23
+
memset(buf, '\0', sizeof(buf));
24
24
+
}
16
25
17
17
-
try (bind(sock, (const struct sockaddr*)&name, sizeof(name)));
26
26
+
desenchufa(cliente);
27
27
+
}
28
28
+
return NULL;
29
29
+
}
18
30
19
19
-
try (listen(sock, 3));
20
20
-
log_info("Listening on socket.");
21
31
22
22
-
int client = accept(sock, (struct sockaddr*)&name, &addrlen);
23
23
-
log_info("Accepted client connection.");
32
32
+
int main() {
33
33
+
EnchufeFD fd = enchufa();
34
34
+
log_info("Socket's file descriptor is: %d\n", fd);
24
35
25
25
-
if (client == -1) {
26
26
-
fprintf(stderr, "[ERROR]: Client connection: %s\n", strerror(errno));
27
27
-
return 1;
28
28
-
}
36
36
+
Enchufe enchufe = amarra(fd, (IPv4){127,0,0,1}, 42069);
29
37
30
30
-
char msg[] = "[ECHO]: You have succesfully connected to the echo server.\n";
31
31
-
send(client, msg, strlen(msg), 0);
38
38
+
escucha(enchufe, 5);
39
39
+
log_info("Listening for a client to connect.\n");
32
40
33
33
-
/*
34
34
-
* Time to read :3
35
35
-
*/
36
36
-
char buf[0x100] = {0};
37
37
-
while (1) {
38
38
-
try (read(client, buf, 0x100 - 1));
39
39
-
if (buf[0] == 'q' && strlen(buf) == 1) break;
40
40
-
send(client, buf, strlen(buf), 0);
41
41
-
size_t len = strlen(buf);
42
42
-
for (size_t i = 0; i < len; ++i) buf[i] = '\0';
43
43
-
}
41
41
+
pthread_t threads[THREAD_COUNT];
42
42
+
for (size_t i = 0; i < THREAD_COUNT; ++i)
43
43
+
pthread_create(&threads[i], NULL, echo, (void*)&enchufe);
44
44
+
for (size_t i = 0; i < THREAD_COUNT; ++i)
45
45
+
pthread_join(threads[i], NULL);
44
46
45
45
-
46
46
-
47
47
-
close(client);
48
48
-
close(sock);
47
47
+
desenchufa(enchufe);
49
48
return 0;
50
49
}
-34
src/socket.c
···
1
1
-
#include <sys/socket.h>
2
2
-
#include <netinet/in.h>
3
3
-
#include "socket.h"
4
4
-
#include "utils.h"
5
5
-
6
6
-
Socket get_socket(enum SocketType type, uint32_t addr, uint16_t port) {
7
7
-
struct sockaddr_in name = {
8
8
-
.sin_family = AF_INET,
9
9
-
.sin_addr.s_addr = htonl(addr),
10
10
-
.sin_port = htons(port),
11
11
-
};
12
12
-
13
13
-
int sock;
14
14
-
switch (type) {
15
15
-
case TCP: {
16
16
-
try (sock = socket(PF_INET, SOCK_STREAM, 0));
17
17
-
} break;
18
18
-
case UDP: {
19
19
-
try (sock = socket(PF_INET, SOCK_DGRAM, 0));
20
20
-
} break;
21
21
-
default: {
22
22
-
fprintf(stderr, "[ERROR]: Bad SocketType.\n");
23
23
-
exit (EXIT_FAILURE);
24
24
-
};
25
25
-
};
26
26
-
27
27
-
try (bind(sock, (const struct sockaddr*)&name, sizeof(name)));
28
28
-
29
29
-
return (Socket){
30
30
-
.socket = sock,
31
31
-
.addr = name,
32
32
-
.addrlen = sizeof(name)
33
33
-
};
34
34
-
}
-18
src/socket.h
···
1
1
-
#ifndef SOCKET_H_
2
2
-
#define SOCKET_H_
3
3
-
#include <stdint.h>
4
4
-
#include <netinet/in.h>
5
5
-
6
6
-
enum SocketType {
7
7
-
TCP,
8
8
-
UDP,
9
9
-
};
10
10
-
11
11
-
typedef struct {
12
12
-
int socket;
13
13
-
struct sockaddr_in addr;
14
14
-
socklen_t addrlen;
15
15
-
} Socket;
16
16
-
17
17
-
Socket get_socket(enum SocketType type, uint32_t addr, uint16_t port);
18
18
-
#endif // SOCKET_H_ header
-15
src/utils.h
···
1
1
-
#ifndef UTILS_H_
2
2
-
#define UTILS_H_
3
3
-
#include <stdio.h>
4
4
-
#include <stdlib.h>
5
5
-
#include <string.h>
6
6
-
#include <errno.h>
7
7
-
8
8
-
#define try(a) do { \
9
9
-
if ((a) < 0) { \
10
10
-
fprintf(stderr, "[ERROR]: Error connecting socket: %s\n", strerror(errno)); \
11
11
-
exit (EXIT_FAILURE); \
12
12
-
} \
13
13
-
} while(0)
14
14
-
15
15
-
#endif // UTILS_H_ header