ubuntu下创建TCP Server步骤,附完整代码

1. 创建套接字

int server_socket = socket(AF_INET, SOCK_STREAM, 0);

socket() 函数本身返回的是一个文件描述符, “Linux下一切皆文件”

2. 创建一个用于初始化socket的地址结构体

    struct sockaddr_in server_addr;
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = inet_addr("0.0.0.0");
    server_addr.sin_port = htons(6969);

struct sockaddr_in 是一个专门用于表示 IPv4 地址的结构体。

除此之外,还有struct sockaddr也是用来表示地址的结构体,但是sockaddr 是一个通用的地址结构体,可以用来表示不同类型的地址,比如 IPv4、IPv6、Unix 域套接字等。它是所有具体地址类型结构体的基类。

3. 将地址绑定到套接字中

bind(server_socket, (struct sockaddr*)&server_addr, sizeof(server_addr));

4. 对此套接字进行监听

listen(server_socket, 5);

其中的5,表示表示半连接与全连接的最大个数,简单来说就是:允许此服务端连接的客户端的最大数量

5. 接受客户端的连接

struct sockaddr_in client_adr;
socklen_t len = sizeof(client_adr);
accept(server_socket, (struct sockaddr*)&client_adr, &len);
    
// 打印信息
printf("client %s:%d connected\n",inet_ntoa(client_adr.sin_addr), ntohs(client_adr.sin_port));

若有客户端连接,则可使用accept()函数接受连接,此函数会将连接的客户端信息放到client_adr结构体中

可使用inet_ntoa(client_adr.sin_addr), ntohs(client_adr.sin_port)获取客户端信息

6. 接收数据

recv(client_socket, recv_buf, 1024, 0)

对指定socket接收数据,并放到recv_buf中,最大值为1024,Flag为0(Flag: 略)

注意:

1. 若此函数返回: -1,则代表接受失败
2. 若此函数返回: 0,则代表对方关闭连接

7. 通信完毕,关闭套接字

    close(client_socket);
    close(server_socket);

完整代码

//
// Created by JIN on 25-2-2.
//

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



int main()
{
    // 1. 变量定义:套接字描述符、地址
    int server_socket, client_socket;
    struct sockaddr_in server_addr, client_adr;

    // 2. 创建套接字
    server_socket = socket(AF_INET, SOCK_STREAM, 0);
    if (server_socket == -1)
    {
        perror("create server_socket failed: ");
        exit(0);
    }

    // 3. 初始化地址
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = inet_addr("0.0.0.0");
    server_addr.sin_port = htons(6969);

    // 4. 套接字绑定地址
    if (bind(server_socket, (struct sockaddr*)&server_addr, sizeof(server_addr)) == -1)
    {
        perror("bind failed: ");
        close(server_socket);
        exit(0);
    }
    printf("socket bind successful\n");

    // 5. 监听
    listen(server_socket, 5);
    printf("listening...\n");

    // 6. 接收连接
    socklen_t len = sizeof(client_adr);
    client_socket = accept(server_socket, (struct sockaddr*)&client_adr, &len);
    if (client_socket == -1)
    {
        perror("accept error: ");
        close(client_socket);
        close(server_socket);
        exit(0);
    }
    printf("client %s:%d connected\n",inet_ntoa(client_adr.sin_addr), ntohs(client_adr.sin_port));

    // 7. 接收数据
    ssize_t recv_num = 0;
    bool EXIT_FLAG = false;
    char recv_buf[1024] = {0};
    do
    {
        // 1. 接收数据
        recv_num = recv(client_socket, recv_buf, 1024, 0);
        /*
         * 返回值:
         *  -1: 接收失败
         *  0 : 对方关闭连接
         */
        if (recv_num == -1)
        {
            perror("recv error: ");
            continue;
        }
        else if (recv_num == 0)
        {
            printf("client close connect\n");
            break;
        }

        // 2. 打印数据
        printf("recv %ld bytes: %s\n", recv_num, recv_buf);

        // 3. 判断退出FLAG
        if (strcmp(recv_buf, "EXIT") == 0)
            EXIT_FLAG = true;

        // 4. 清空缓存
        memset(recv_buf, 0, recv_num);
        recv_num = 0;

    }while (!EXIT_FLAG);

    // 8. 关闭连接
    close(client_socket);
    close(server_socket);
    printf("socket closed!\n");

    return 0;
}

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