直接上代码解释TCP/UDP

文章目录

    • TCP协议
    • UDP协议

TCP协议

TCP是一种可靠的面向连接的协议,它提供了可靠的数据传输和错误修复机制。这使得TCP广泛用于需要可靠数据传输的应用,例如电子邮件、文件传输和Web浏览器。

当使用TCP建立连接时,它会在客户端和服务器之间创建一个虚拟的连接,并确保数据在这个连接上按照正确的顺序传输。这是通过使用序列号、确认号和窗口大小等机制来实现的。

下面是一个使用TCP的简单示例,展示了如何在服务器和客户端之间建立连接并进行通信:

服务器端(server.c):

#include 
#include 
#include 
#include 
#include 
#include 

#define PORT 8080
#define BUFFER_SIZE 1024

int main() {
    int sockfd, client_sockfd;
    struct sockaddr_in server_addr, client_addr;
    char buffer[BUFFER_SIZE];
    
    // 创建套接字
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd == -1) {
        perror("socket");
        return 1;
    }
    
    // 设置服务器地址
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(PORT);
    server_addr.sin_addr.s_addr = INADDR_ANY;
    
    // 绑定套接字到服务器地址
    if (bind(sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr)) == -1) {
        perror("bind");
        return 1;
    }
    
    // 监听请求
    listen(sockfd, 5);
    
    printf("Server started. Waiting for connections...\n");
    
    while (1) {
        // 接受连接
        int client_addr_len = sizeof(client_addr);
        client_sockfd = accept(sockfd, (struct sockaddr*)&client_addr, &client_addr_len);
        if (client_sockfd == -1) {
            perror("accept");
            return 1;
        }
        
        // 读取客户端发送的消息
        memset(buffer, 0, BUFFER_SIZE);
        read(client_sockfd, buffer, BUFFER_SIZE);
        printf("Received message from client: %s\n", buffer);
        
        // 发送响应给客户端
        write(client_sockfd, "Message received!", strlen("Message received!"));
        
        // 关闭客户端套接字
        close(client_sockfd);
    }
    
    // 关闭服务器套接字
    close(sockfd);
    
    return 0;
}

客户端(client.c):

#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define PORT 8080
#define BUFFER_SIZE 1024

int main() {
    int sockfd;
    struct sockaddr_in server_addr;
    char buffer[BUFFER_SIZE];
    
    // 创建套接字
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd == -1) {
        perror("socket");
        return 1;
    }
    
    // 设置服务器地址
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(PORT);
    server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
    
    // 连接服务器
    if (connect(sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr)) == -1) {
        perror("connect");
        return 1;
    }
    
    // 发送消息给服务器
    printf("Enter message to send to server: ");
    fgets(buffer, BUFFER_SIZE, stdin);
    write(sockfd, buffer, strlen(buffer));
    
    // 读取服务器的响应
    memset(buffer, 0, BUFFER_SIZE);
    read(sockfd, buffer, BUFFER_SIZE);
    printf("Server response: %s\n", buffer);
    
    // 关闭套接字
    close(sockfd);
    
    return 0;
}

以上是一个使用TCP的简单示例。在服务器端,我们首先创建一个套接字,绑定地址和端口,并开始监听客户端连接。当有客户端请求连接时,我们接受连接,读取客户端发送的消息并给出响应。在客户端,我们创建一个套接字,连接到服务器,并发送消息给服务器并读取响应。

UDP协议

UDP是一种无连接的协议,它提供了一种简单的数据传输机制,适用于一些不需要可靠数据传输的应用,例如游戏、流媒体和实时通信。

与TCP不同,UDP没有建立连接的过程,而是直接发送和接收数据包。UDP也不提供错误修复机制,数据包可能会丢失或乱序到达。因此,在使用UDP时,我们需要自己处理数据的可靠性和顺序问题。

以下是一个使用UDP的简单示例,展示了如何在客户端和服务器之间进行通信:

服务器端(server.c):

#include 
#include 
#include 
#include 
#include 
#include 

#define PORT 8080
#define BUFFER_SIZE 1024

int main() {
    int sockfd;
    struct sockaddr_in server_addr, client_addr;
    char buffer[BUFFER_SIZE];
    
    // 创建套接字
    sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (sockfd == -1) {
        perror("socket");
        return 1;
    }
    
    // 设置服务器地址
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(PORT);
    server_addr.sin_addr.s_addr = INADDR_ANY;
    
    // 绑定套接字到服务器地址
    if (bind(sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr)) == -1) {
        perror("bind");
        return 1;
    }
    
    printf("Server started. Waiting for messages...\n");
    
    while (1) {
        // 接收消息
        memset(buffer, 0, BUFFER_SIZE);
        socklen_t client_addr_len = sizeof(client_addr);
        ssize_t bytes_received = recvfrom(sockfd, buffer, BUFFER_SIZE, 0, (struct sockaddr*)&client_addr, &client_addr_len);
        if (bytes_received == -1) {
            perror("recvfrom");
            return 1;
        }
        
        printf("Received message from client: %s\n", buffer);
        
        // 回复消息给客户端
        char *response = "Message received!";
        ssize_t bytes_sent = sendto(sockfd, response, strlen(response), 0, (struct sockaddr*)&client_addr, client_addr_len);
        if (bytes_sent == -1) {
            perror("sendto");
            return 1;
        }
    }
    
    // 关闭套接字
    close(sockfd);
    
    return 0;
}

客户端(client.c):

#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define PORT 8080
#define BUFFER_SIZE 1024

int main() {
    int sockfd;
    struct sockaddr_in server_addr;
    char buffer[BUFFER_SIZE];
    
    // 创建套接字
    sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (sockfd == -1) {
        perror("socket");
        return 1;
    }
    
    // 设置服务器地址
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(PORT);
    server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
    
    // 发送消息给服务器
    printf("Enter message to send to server: ");
    fgets(buffer, BUFFER_SIZE, stdin);
    ssize_t bytes_sent = sendto(sockfd, buffer, strlen(buffer), 0, (struct sockaddr*)&server_addr, sizeof(server_addr));
    if (bytes_sent == -1) {
        perror("sendto");
        return 1;
    }
    
    // 接收服务器的响应
    memset(buffer, 0, BUFFER_SIZE);
    socklen_t server_addr_len = sizeof(server_addr);
    ssize_t bytes_received = recvfrom(sockfd, buffer, BUFFER_SIZE, 0, (struct sockaddr*)&server_addr, &server_addr_len);
    if (bytes_received == -1) {
        perror("recvfrom");
        return 1;
    }
    
    printf("Server response: %s\n", buffer);
    
    // 关闭套接字
    close(sockfd);
    
    return 0;
}

在UDP示例中,服务器端和客户端的代码都有所变化。服务器端使用了recvfrom()sendto()函数来接收和发送数据包,而不是读取和写入文件描述符。客户端同样使用了recvfrom()sendto()函数来接收和发送数据包。

你可能感兴趣的:(物联网,tcp/ip,udp,网络)