04_intro_to_sockets: working tcp example
add .gitignore and remove executeables and object files
This commit is contained in:
parent
a29cccd3ea
commit
66c8612401
|
|
@ -0,0 +1,2 @@
|
||||||
|
obj/
|
||||||
|
bin/
|
||||||
|
|
@ -13,6 +13,7 @@ static struct gpiod_line *button_line = NULL;
|
||||||
// Error handling function
|
// Error handling function
|
||||||
static int handle_error(const char *msg) {
|
static int handle_error(const char *msg) {
|
||||||
perror(msg);
|
perror(msg);
|
||||||
|
cleanup_gpio()
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,11 @@
|
||||||
|
# Compiler and flags
|
||||||
CC = gcc
|
CC = gcc
|
||||||
CFLAGS = -Wall -Ilib
|
CFLAGS = -Wall -Ilib
|
||||||
#LDFLAGS = -lgpiod
|
|
||||||
|
|
||||||
# Directories
|
# Directories
|
||||||
SRCDIR = src
|
SRCDIR = src
|
||||||
LIBDIR = lib
|
LIBDIR = lib
|
||||||
|
BINDIR = bin
|
||||||
OBJDIR = obj
|
OBJDIR = obj
|
||||||
|
|
||||||
# Source files
|
# Source files
|
||||||
|
|
@ -13,27 +14,26 @@ SRC_SOURCES = $(wildcard $(SRCDIR)/*.c)
|
||||||
|
|
||||||
# Object files
|
# Object files
|
||||||
LIB_OBJECTS = $(LIB_SOURCES:$(LIBDIR)/%.c=$(OBJDIR)/%.o)
|
LIB_OBJECTS = $(LIB_SOURCES:$(LIBDIR)/%.c=$(OBJDIR)/%.o)
|
||||||
SRC_OBJECTS = $(SRC_SOURCES:$(SRCDIR)/%.c=$(OBJDIR)/%.o)
|
|
||||||
|
|
||||||
# Target executable
|
# Executables
|
||||||
TARGET = sockets
|
EXECS = $(SRC_SOURCES:$(SRCDIR)/%.c=$(BINDIR)/%)
|
||||||
|
|
||||||
# Create obj directory if it doesn't exist
|
# Create necessary directories
|
||||||
$(shell mkdir -p $(OBJDIR))
|
$(shell mkdir -p $(OBJDIR))
|
||||||
|
$(shell mkdir -p $(BINDIR))
|
||||||
|
|
||||||
# Rules
|
# Rules
|
||||||
all: $(TARGET)
|
all: $(EXECS)
|
||||||
|
|
||||||
$(TARGET): $(LIB_OBJECTS) $(SRC_OBJECTS)
|
$(BINDIR)/%: $(SRCDIR)/%.c $(LIB_OBJECTS)
|
||||||
$(CC) $(LIB_OBJECTS) $(SRC_OBJECTS) -o $@ $(LDFLAGS)
|
$(CC) $(CFLAGS) -o $@ $< $(LIB_OBJECTS)
|
||||||
|
|
||||||
$(OBJDIR)/%.o: $(LIBDIR)/%.c
|
$(OBJDIR)/%.o: $(LIBDIR)/%.c
|
||||||
$(CC) $(CFLAGS) -c $< -o $@
|
$(CC) $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
$(OBJDIR)/%.o: $(SRCDIR)/%.c
|
|
||||||
$(CC) $(CFLAGS) -c $< -o $@
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f $(OBJDIR)/*.o $(TARGET)
|
rm -f $(OBJDIR)/*.o
|
||||||
|
rm -f $(BINDIR)/*
|
||||||
|
|
||||||
.PHONY: all clean
|
.PHONY: all clean
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,5 +7,5 @@ a LED, a button and a temperature sensor.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ make
|
$ make
|
||||||
$ ./io
|
$ ./sockets
|
||||||
```
|
```
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,113 @@
|
||||||
|
#include <arpa/inet.h> // For inet_addr(), htons()
|
||||||
|
#include <stdio.h> // For printf()
|
||||||
|
#include <stdlib.h> // For exit()
|
||||||
|
#include <string.h> // For memset()
|
||||||
|
#include <sys/socket.h> // For socket(), connect(), read(), write()
|
||||||
|
#include <time.h>
|
||||||
|
#include <unistd.h> // For close()
|
||||||
|
#include "sockets.h"
|
||||||
|
|
||||||
|
#define BUFFER_SIZE 1024
|
||||||
|
|
||||||
|
static void error_handling(char *message, int sock) {
|
||||||
|
perror(message);
|
||||||
|
close(sock);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int tcp_create_socket() {
|
||||||
|
// PF_INET: IPv4, SOCK_STREAM: TCP
|
||||||
|
int sock = socket(PF_INET, SOCK_STREAM, 0);
|
||||||
|
if (sock == -1)
|
||||||
|
error_handling("socket() error", sock);
|
||||||
|
return sock;
|
||||||
|
}
|
||||||
|
|
||||||
|
void connect_to_server(int sock, char *ip, int port) {
|
||||||
|
struct sockaddr_in serv_addr;
|
||||||
|
// Initialize serv_addr to zero
|
||||||
|
memset(&serv_addr, 0, sizeof(serv_addr));
|
||||||
|
// Set the address family to IPv4
|
||||||
|
serv_addr.sin_family = AF_INET;
|
||||||
|
// Convert IP address to binary form
|
||||||
|
serv_addr.sin_addr.s_addr = inet_addr(ip);
|
||||||
|
// Convert port number to network byte order
|
||||||
|
serv_addr.sin_port = htons(port);
|
||||||
|
|
||||||
|
if (connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) == -1)
|
||||||
|
error_handling("connect() error", sock);
|
||||||
|
}
|
||||||
|
|
||||||
|
char* communicate(int sock, char *message) {
|
||||||
|
// Sending the ASCII string
|
||||||
|
if (write(sock, message, strlen(message)) == -1)
|
||||||
|
error_handling("write() error", sock);
|
||||||
|
|
||||||
|
// Receiving response
|
||||||
|
char* response = malloc(BUFFER_SIZE);
|
||||||
|
if (!response)
|
||||||
|
error_handling("Failed to allocate memory for response", sock);
|
||||||
|
|
||||||
|
int str_len = read(sock, response, BUFFER_SIZE - 1);
|
||||||
|
if (str_len == -1){
|
||||||
|
free(response);
|
||||||
|
error_handling("read() error", sock);
|
||||||
|
} else if (str_len == 0) {
|
||||||
|
printf("Server closed the connection.\n");
|
||||||
|
free(response);
|
||||||
|
return NULL;
|
||||||
|
} else {
|
||||||
|
response[str_len] = '\0'; // Null-terminate the received data
|
||||||
|
}
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
int tcp_listen(int port) {
|
||||||
|
int sock = tcp_create_socket();
|
||||||
|
|
||||||
|
struct sockaddr_in serv_addr;
|
||||||
|
memset(&serv_addr, 0, sizeof(serv_addr));
|
||||||
|
serv_addr.sin_family = AF_INET;
|
||||||
|
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||||
|
serv_addr.sin_port = htons(port);
|
||||||
|
|
||||||
|
if (bind(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) == -1)
|
||||||
|
error_handling("bind() error", sock);
|
||||||
|
|
||||||
|
if (listen(sock, 5) == -1)
|
||||||
|
error_handling("listen() error", sock);
|
||||||
|
|
||||||
|
return sock;
|
||||||
|
}
|
||||||
|
|
||||||
|
int tcp_accept(int serv_sock) {
|
||||||
|
struct sockaddr_in clnt_addr;
|
||||||
|
socklen_t clnt_addr_size = sizeof(clnt_addr);
|
||||||
|
int clnt_sock = accept(serv_sock, (struct sockaddr*)&clnt_addr, &clnt_addr_size);
|
||||||
|
if (clnt_sock == -1)
|
||||||
|
error_handling("accept() error", clnt_sock);
|
||||||
|
return clnt_sock;
|
||||||
|
}
|
||||||
|
|
||||||
|
void process_request(int clnt_sock) {
|
||||||
|
char message[BUFFER_SIZE];
|
||||||
|
int str_len = read(clnt_sock, message, BUFFER_SIZE - 1);
|
||||||
|
if (str_len == -1)
|
||||||
|
// TODO: clnt_sock might be a bug
|
||||||
|
error_handling("read() error", clnt_sock);
|
||||||
|
|
||||||
|
message[str_len] = '\0'; // Null-terminate the string
|
||||||
|
|
||||||
|
time_t t = time(NULL);
|
||||||
|
struct tm *timeinfo;
|
||||||
|
|
||||||
|
if (strcmp(message, "1") == 0) {
|
||||||
|
timeinfo = localtime(&t); // Local time
|
||||||
|
} else {
|
||||||
|
timeinfo = gmtime(&t); // GMT time
|
||||||
|
}
|
||||||
|
|
||||||
|
strftime(message, BUFFER_SIZE, "%Y-%m-%d %H:%M:%S", timeinfo);
|
||||||
|
write(clnt_sock, message, strlen(message));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -1,5 +1,22 @@
|
||||||
#ifndef SOCKETS_LIB_H
|
#ifndef SOCKETS_LIB_H
|
||||||
#define SOCKETS_LIB_H
|
#define SOCKETS_LIB_H
|
||||||
|
|
||||||
|
// Function to create a TCP socket
|
||||||
|
int tcp_create_socket();
|
||||||
|
|
||||||
#endif // SOCKETS_H
|
// Function to connect to a server
|
||||||
|
void connect_to_server(int sock, char *ip, int port);
|
||||||
|
|
||||||
|
// Function to communicate with the server
|
||||||
|
char* communicate(int sock, char *message);
|
||||||
|
|
||||||
|
// Function to create a TCP server socket
|
||||||
|
int tcp_listen(int port);
|
||||||
|
|
||||||
|
// Function to accept a client connection
|
||||||
|
int tcp_accept(int serv_sock);
|
||||||
|
|
||||||
|
// Function to process a client request
|
||||||
|
void process_request(int clnt_sock);
|
||||||
|
|
||||||
|
#endif // SOCKETS_LIB_H
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
#include <stdio.h> // For printf()
|
||||||
|
#include <unistd.h> // For close()
|
||||||
|
#include <stdlib.h> // For exit(), atoi()
|
||||||
|
#include "sockets.h"
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
if (argc != 4) {
|
||||||
|
printf("Usage : %s <IP> <port> <message_to_send>\n", argv[0]);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int sock = tcp_create_socket();
|
||||||
|
connect_to_server(sock, argv[1], atoi(argv[2]));
|
||||||
|
char* received_data = communicate(sock, argv[3]);
|
||||||
|
if (received_data) {
|
||||||
|
printf("Received from server: %s\n", received_data);
|
||||||
|
free(received_data);
|
||||||
|
}
|
||||||
|
close(sock);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include "sockets.h"
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
if (argc != 2) {
|
||||||
|
printf("Usage: %s <port>\n", argv[0]);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int port = atoi(argv[1]);
|
||||||
|
int serv_sock = tcp_listen(port);
|
||||||
|
int clnt_sock = tcp_accept(serv_sock);
|
||||||
|
|
||||||
|
process_request(clnt_sock);
|
||||||
|
close(clnt_sock);
|
||||||
|
close(serv_sock);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
@ -1,4 +0,0 @@
|
||||||
|
|
||||||
int main() {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue