Networking System Calls | Generated by AI
In operating systems like Linux/Unix, the lowest-level system calls for networking, particularly for establishing a TCP connection, come from the Berkeley Sockets API (often just called “sockets”). These system calls interact directly with the kernel’s networking stack. The most fundamental ones for TCP connections are:
socket()- Creates a new socket.bind()- Assigns an address to the socket (optional for clients).connect()- Initiates a connection to a remote server (for clients).listen()- Marks the socket as accepting connections (for servers).accept()- Accepts an incoming connection (for servers).send()/recv()- Sends or receives data over the connection.close()- Closes the socket.
These are the raw system calls you’d use at the lowest level, below any higher-level libraries like libcurl or frameworks. Here’s a simple example in C showing both a TCP client and server establishing a connection.
TCP Server Example
This code sets up a server that listens for a connection on port 8080, accepts it, and sends a message.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
int main() {
int server_fd, client_fd;
struct sockaddr_in server_addr, client_addr;
socklen_t client_len = sizeof(client_addr);
char *message = "Hello from server!\n";
// Create socket
server_fd = socket(AF_INET, SOCK_STREAM, 0);
if (server_fd == -1) {
perror("Socket creation failed");
exit(EXIT_FAILURE);
}
// Set up server address structure
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = INADDR_ANY; // Bind to any address
server_addr.sin_port = htons(8080); // Port 8080
// Bind socket
if (bind(server_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
perror("Bind failed");
exit(EXIT_FAILURE);
}
// Listen for connections
if (listen(server_fd, 3) < 0) { // Allow up to 3 queued connections
perror("Listen failed");
exit(EXIT_FAILURE);
}
printf("Server listening on port 8080...\n");
// Accept incoming connection
client_fd = accept(server_fd, (struct sockaddr *)&client_addr, &client_len);
if (client_fd < 0) {
perror("Accept failed");
exit(EXIT_FAILURE);
}
printf("Connection accepted\n");
// Send message to client
send(client_fd, message, strlen(message), 0);
// Clean up
close(client_fd);
close(server_fd);
return 0;
}
TCP Client Example
This code connects to the server at 127.0.0.1:8080 and reads the message.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
int main() {
int sock_fd;
struct sockaddr_in server_addr;
char buffer[1024] = {0};
// Create socket
sock_fd = socket(AF_INET, SOCK_STREAM, 0);
if (sock_fd == -1) {
perror("Socket creation failed");
exit(EXIT_FAILURE);
}
// Set up server address structure
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(8080); // Port 8080
inet_pton(AF_INET, "127.0.0.1", &server_addr.sin_addr); // Localhost
// Connect to server
if (connect(sock_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
perror("Connection failed");
exit(EXIT_FAILURE);
}
printf("Connected to server\n");
// Receive message from server
recv(sock_fd, buffer, sizeof(buffer), 0);
printf("Server message: %s", buffer);
// Clean up
close(sock_fd);
return 0;
}
Explanation of Key System Calls
socket(AF_INET, SOCK_STREAM, 0): Creates a TCP socket (AF_INETfor IPv4,SOCK_STREAMfor TCP).bind(): Associates the socket with a local address and port (server-side).listen(): Prepares the socket to accept connections (server-side).accept(): Blocks until a client connects, then returns a new socket for communication.connect(): Initiates a TCP handshake with the server (client-side).send()/recv(): Handle data transfer over the established connection.close(): Terminates the socket.
These are as low-level as it gets for TCP networking in user space. Below this, you’d be dealing with kernel internals (e.g., the TCP/IP stack itself), which isn’t directly accessible via system calls without writing kernel code.
To compile and run:
- Save the server code as
server.cand client code asclient.c. - Compile:
gcc server.c -o serverandgcc client.c -o client. - Run the server first:
./server. - In another terminal, run the client:
./client.
Let me know if you want more details or a deeper dive!