In modern network communication, the TCP/IP protocol stack is one of the most important foundations. It provides a standardized method for communication between computers. In this article, we will delve into how to perform TCP/IP programming using the C language, demonstrating basic client and server implementations through example code.
1. Overview of TCP/IP Protocol Stack
TCP/IP (Transmission Control Protocol/Internet Protocol) is a set of protocols used for network communication. It is divided into four layers:
- Application Layer: Handles data for specific applications, such as HTTP, FTP, etc.
- Transport Layer: Responsible for the reliability and order of data transmission, mainly TCP and UDP.
- Network Layer: Responsible for routing data packets across the network, primarily using IP.
- Link Layer: Handles physical connections and data frames.
In this tutorial, we will focus on the interaction between the application layer and the transport layer, implementing a simple TCP client and server in C language.
2. Environment Setup
Ensure that your development environment has a C compiler (such as GCC) and the necessary development libraries installed. On Linux systems, you can compile and run directly from the terminal.
3. TCP Server Implementation
Below is a simple example of TCP server code that listens on a specified port and accepts messages from clients:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#define PORT 8080
#define BUFFER_SIZE 1024
int main() {
int server_fd, new_socket;
struct sockaddr_in address;
int opt = 1;
int addrlen = sizeof(address);
char buffer[BUFFER_SIZE] = {0};
// Create socket
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
perror("socket failed");
exit(EXIT_FAILURE);
}
// Set socket options to allow address reuse
if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) {
perror("setsockopt");
exit(EXIT_FAILURE);
}
// Set address structure
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY; // Accept any IP address
address.sin_port = htons(PORT); // Convert to network byte order
// Bind socket to specified port
if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {
perror("bind failed");
exit(EXIT_FAILURE);
}
// Start listening for connection requests
if (listen(server_fd, 3) < 0) {
perror("listen");
exit(EXIT_FAILURE);
}
printf("Waiting for connections...\n");
while(1) {
// Accept new connection requests
if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen)) < 0) {
perror("accept");
exit(EXIT_FAILURE);
}
read(new_socket , buffer, BUFFER_SIZE);
printf("Received message: %s\n", buffer);
const char *response = "Message received";
send(new_socket , response , strlen(response), 0 );
close(new_socket);
}
return 0;
}
Program Explanation:
- Create a socket and set options to allow address reuse.
- Use the
<span>bind()</span>function to bind the socket to the specified port. - Call
<span>listen()</span>to start listening for connection requests. - In a loop, accept new connections from clients, read the sent messages, and return a response.
4. TCP Client Implementation
Below is a simple example of TCP client code that sends a message to the server and waits for a response:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#define PORT 8080
#define BUFFER_SIZE 1024
int main() {
int sock = 0;
struct sockaddr_in serv_addr;
char *message = "Hello, Server!";
char buffer[BUFFER_SIZE] = {0};
// Create socket file descriptor
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
printf("\n Socket creation failed \n");
return -1;
}
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(PORT);
// Convert IPv4 address from text to binary form
if(inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr) <= 0) {
printf("\n Invalid address/ Address not supported \n");
return -1;
}
// Attempt to connect to the server
if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
printf("\n Connection failed \n");
return -1;
}
send(sock , message , strlen(message), MSG_NOSIGNAL);
read(sock , buffer , BUFFER_SIZE);
printf("%s\n", buffer);
close(sock);
return 0;
}
Program Explanation:
- Create a socket for communication with the server.
- Set the target server information, including IP address and port number.
- Use the
<span>connect()</span>function to attempt to establish a connection with the server. - Send a message to the server and read the information returned by the server.
Conclusion
Through the above two simple examples, we have demonstrated how to perform basic TCP/IP programming using the C language. You can expand these codes according to your needs, such as adding multi-threading support, error handling mechanisms, etc. These foundational knowledge are crucial for understanding more complex network applications, and we hope this article helps you get started with TCP/IP programming in C language!