Lecture Notes: 19 Network Client
··2 mins
Writing a TCP in C #
Network layers:
- Machines on the internet have an IP address
- IP packets are stateless, unreliable, and don’t guarantee order
- Over IP is TCP, which uses retransmission and buffering to simulate a stream
- 64k TCP ports
Here’s some starter code mostly generated by an LLM:
```C
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#define MAX_BUFFER 1024
int main(int argc, char *argv[]) {
if (argc != 3) {
fprintf(stderr, "Usage: %s <host> <port>\n", argv[0]);
exit(1);
}
// Create socket
int sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0) {
perror("Socket creation failed");
exit(1);
}
// Set up server address
struct sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(atoi(argv[2]));
if (inet_pton(AF_INET, argv[1], &server_addr.sin_addr) < 0) {
perror("Invalid address");
close(sock);
exit(1);
}
// Connect to server
if (connect(sock, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) {
perror("Connection failed");
close(sock);
exit(1);
}
// Send "hello\r\n"
const char *msg = "GET / HTTP/1.0\r\n\r\n";
if (send(sock, msg, strlen(msg), 0) < 0) {
perror("Send failed");
close(sock);
exit(1);
}
// Receive response
char buffer[MAX_BUFFER] = {0};
int bytes_received = recv(sock, buffer, MAX_BUFFER - 1, 0);
if (bytes_received < 0) {
perror("Receive failed");
} else if (bytes_received == 0) {
printf("Server closed connection\n");
} else {
// Ensure buffer is null-terminated and print the response
buffer[bytes_received] = '\0';
printf("%s", buffer);
}
// Clean up
close(sock);
return 0;
}
Using that, we can write a quick and dirty HTTP client.