• C语言Socket示例


    1. Socket客户端

    2. Socket服务器(单进程单连接)

    3. Socket服务器(多进程多连接) 

    4. Socket服务器(多线程多连接)

     

    1. Socket客户端

    #include <sys/types.h>
    #include <sys/socket.h>
    #include <stdio.h>
    #include <unistd.h>
    #include <string.h>
    #include <arpa/inet.h>
    
    #define PORT 8088
    #define SIZE 1024
    
    int main() {
    
        // int socket(int family, int type, int protocol);
        int client_socket = socket(AF_INET, SOCK_STREAM, 0);    // 创建一个Socket,返回大于0的文件描述符。
        if(client_socket == -1){
            perror("socket");
            return -1;
        }
    
        // 定义sockaddr_in结构体
        struct sockaddr_in addr;
        memset(&addr, 0, sizeof(addr));
        addr.sin_family = AF_INET;  // 标记为IPv4
        addr.sin_port = htons(PORT);    // 绑定端口
        addr.sin_addr.s_addr = inet_addr("172.16.37.130");  // 指定Server IP地址
    
        // int connect(int sock_fd, struct sockaddr *server_addr,int addr_len);
        int conn = connect(client_socket, (struct sockaddr *)&addr, sizeof(addr));   // 向服务器发送连接请求。
        if(conn == -1){
            perror("connect");
            return -1;
        }
        printf("成功连接到一个服务器
    ");
    
        char buf[SIZE] = {0};
        while (1){
            printf("请输入你想输入的:");
            scanf("%s", buf);
            write(client_socket, buf, strlen(buf));    // 向Socket文件描述符写入内容
            int ret = read(client_socket, buf, strlen(buf));    // 从Socket文件描述符中读取内容
            printf("ret size : %d
    ", ret);
            printf("buf = %s
    ", buf);
            if(strncmp(buf, "END", 3) == 0){
                break;
            }
        }
        close(client_socket);   // 关闭Socket文件描述符
        return 0;
    }

    2. Socket服务器(单进程单连接)

    #include <sys/types.h>
    #include <sys/socket.h>
    #include <stdio.h>
    #include <unistd.h>
    #include <string.h>
    #include <arpa/inet.h>
    
    
    #define PORT 8088   //端口号
    #define SIZE 1024   //定义的数组大小
    
    int create_socket()    //创建套接字和初始化以及监听函数
    {
        int listen_socket = socket(AF_INET, SOCK_STREAM, 0);   // 创建一个负责监听的Socket文件描述符
        if (listen_socket == -1) {
            perror("socket");
            return -1;
        }
    
        // 定义socket_addr结构体
        struct sockaddr_in addr;
        memset(&addr, 0, sizeof(addr));
    
        addr.sin_family = AF_INET;  // Internet地址族
        addr.sin_port = htons(PORT);  // 监听端口号
        addr.sin_addr.s_addr = htonl(INADDR_ANY);   // 绑定任何地址
    
        // 将Socket文件描述符和sock_addr进行绑定
        // int bind(int sock_fd, const struct sockaddr *addr, socklen_t addr_len);
        int ret = bind(listen_socket, (struct sockaddr *) &addr, sizeof(addr));
        if (ret == -1) {
            perror("bind");
            return -1;
        }
    
        // 开始监听客户端连接,并限制最大连接数
        ret = listen(listen_socket, 5);
        if (ret == -1) {
            perror("listen");
            return -1;
        }
        return listen_socket;
    }
    
    
    int wait_client(int listen_socket)  // 等待客户端连接处理函数
    {
        struct sockaddr_in client_addr;
        int addr_len = sizeof(client_addr);
        printf("等待客户端连接。。。。
    ");
    
        // 等待客户端连接,并把客户端的协议族、网络地址、端口号都存入client_addr中,然后返回一个客户端fd。
        // int accept(int sock_fd, struct sockaddr *client_addr, socklen_t *len);
        int client_socket = accept(listen_socket, (struct sockaddr *) &client_addr, &addr_len);
        if (client_socket == -1) {
            perror("accept");
            return -1;
        }
    
        printf("成功接收到一个客户端:%s
    ", inet_ntoa(client_addr.sin_addr));
    
        return client_socket;
    }
    
    
    void handle_client(int client_socket)   // 信息处理函数,功能是将客户端传过来的小写字母转化为大写字母
    {
        char buf[SIZE];
        while (1) {
            int ret = read(client_socket, buf, SIZE - 1);   // 从客户端fd中读取内容
            if (ret == -1) {
                perror("read");
                break;
            }
            if (ret == 0) {
                break;
            }
            buf[ret] = '';
            int i;
            for (i = 0; i < ret; i++) {
                buf[i] = buf[i] + 'A' - 'a';
            }
    
            printf("%s
    ", buf);
            write(client_socket, buf, ret);     // 向客户端fd写入内容
    
            if (strncmp(buf, "end", 3) == 0) {
                break;
            }
        }
        close(client_socket);   // 关闭客户端fd
    }
    
    int main() {
        int listen_socket = create_socket();
    
        int client_socket = wait_client(listen_socket);
    
        handle_client(client_socket);
    
        close(listen_socket);
    
        return 0;
    }

    3. Socket服务器(多进程多连接)

    #include <sys/types.h>
    #include <sys/socket.h>
    #include <stdio.h>
    #include <unistd.h>
    #include <string.h>
    #include <arpa/inet.h>
    #include <sys/wait.h>
    
    
    #define PORT 8088   //端口号
    #define SIZE 1024   //定义的数组大小
    
    int create_socket()    //创建套接字和初始化以及监听函数
    {
        int listen_socket = socket(AF_INET, SOCK_STREAM, 0);   // 创建一个负责监听的Socket文件描述符
        if (listen_socket == -1) {
            perror("socket");
            return -1;
        }
    
        // 定义socket_addr结构体
        struct sockaddr_in addr;
        memset(&addr, 0, sizeof(addr));
    
        addr.sin_family = AF_INET;  // Internet地址族
        addr.sin_port = htons(PORT);  // 监听端口号
        addr.sin_addr.s_addr = htonl(INADDR_ANY);   // 绑定任何地址
    
        // 将Socket文件描述符和sock_addr进行绑定
        // int bind(int sock_fd, const struct sockaddr *addr, socklen_t addr_len);
        int ret = bind(listen_socket, (struct sockaddr *) &addr, sizeof(addr));
        if (ret == -1) {
            perror("bind");
            return -1;
        }
    
        // 开始监听客户端连接,并限制最大连接数
        ret = listen(listen_socket, 5);
        if (ret == -1) {
            perror("listen");
            return -1;
        }
        return listen_socket;
    }
    
    
    int wait_client(int listen_socket)  // 等待客户端连接处理函数
    {
        struct sockaddr_in client_addr;
        int addr_len = sizeof(client_addr);
        printf("等待客户端连接。。。。
    ");
    
        // 等待客户端连接,并把客户端的协议族、网络地址、端口号都存入client_addr中,然后返回一个客户端fd。
        // int accept(int sock_fd, struct sockaddr *client_addr, socklen_t *len);
        int client_socket = accept(listen_socket, (struct sockaddr *) &client_addr, &addr_len);
        if (client_socket == -1) {
            perror("accept");
            return -1;
        }
    
        printf("成功接收到一个客户端:%s
    ", inet_ntoa(client_addr.sin_addr));
    
        return client_socket;
    }
    
    
    void handle_client(int client_socket)   // 信息处理函数,功能是将客户端传过来的小写字母转化为大写字母
    {
        char buf[SIZE];
        while (1) {
            int ret = read(client_socket, buf, SIZE - 1);   // 从客户端fd中读取内容
            if (ret == -1) {
                perror("read");
                break;
            }
            if (ret == 0) {
                break;
            }
            buf[ret] = '';
            int i;
            for (i = 0; i < ret; i++) {
                buf[i] = buf[i] + 'A' - 'a';
            }
    
            printf("%s
    ", buf);
            write(client_socket, buf, ret);     // 向客户端fd写入内容
    
            if (strncmp(buf, "end", 3) == 0) {
                break;
            }
        }
        close(client_socket);   // 关闭客户端fd
    }
    
    
    void handler(int sig) {
    
        while (waitpid(-1, NULL, WNOHANG) > 0) {
            printf("成功处理一个子进程的退出
    ");
        }
    }
    
    
    int main() {
        int listen_socket = create_socket();
        signal(SIGCHLD,  handler);    //处理子进程,防止僵尸进程的产生
    
        while(1){
            int client_socket = wait_client(listen_socket);
    
            // 开启一个子进程
            int pid = fork();
            if(pid == -1){
                perror("fork");
                break;
            }
    
            // pid > 0 表示父进程
            if(pid > 0) {
                close(client_socket);
                continue;
            }
    
            // pid = 0 表示子进程
            if(pid == 0){
                close(client_socket);
                handle_client(client_socket);
                break;
            }
        }
    
        close(listen_socket);
        return 0;
    }

    4. Socket服务器(多线程多连接)

  • 相关阅读:
    利用Lambda获取属性名称
    Entity Framework 6.0 源码解读笔记(一)
    [转]Sql server2005中如何格式化时间日期
    python之路_RabbitMQ相关介绍
    python之路_redis相关介绍
    python之路_django之contenttype介绍
    python之路_最简单的Git介绍
    python之路_rest-framework之分页、路由、视图、渲染
    python之路_rest-framework之版本、解析器、序列化
    python之路_rest-framework之认证、权限、频率
  • 原文地址:https://www.cnblogs.com/vincenshen/p/12243848.html
Copyright © 2020-2023  润新知