Untitled

mail@pastecode.io avatarunknown
plain_text
a month ago
2.6 kB
4
Indexable
Never
#include "tcp_server.h"
#include <iostream>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <cstring>


int getClientFd()
{
    static int new_fd = start_server(7000);
    return new_fd;
}

int start_server(int port, const char* host)
{

    int sock_fd;
    sockaddr_in my_addr{};  //用來儲存伺服器的地址資訊。
    int status;
    int on = 1;

    //用 socket 函數來創建一個新的套接字
    sock_fd = socket(AF_INET, SOCK_STREAM, 0); //sock_fd是一個全域整數變數, 代表伺服器的套接字(socket)描述符

    if (sock_fd == -1) {
        perror("Socket creation error");
        return -1;
    }
    
    // 用 setsockopt 函數來設置套接字選項,這裡的選項 SO_REUSEADDR 允許重新使用本地地址和端口
    if (setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(int)) == -1) {
        perror("Setsockopt error");
        return -1;
    }

    my_addr.sin_family = AF_INET;
    inet_aton(host, &my_addr.sin_addr);
    my_addr.sin_port = htons(port);
    
    //bind 函數將套接字與特定的 IP 地址和端口綁定。

    //bind 將伺服器的套接字綁定到特定的IP地址和端口上
    status = bind(sock_fd, reinterpret_cast<struct sockaddr*>(&my_addr), sizeof(my_addr));
    if (status == -1) {
        perror("Binding error");
        return -1;
    }

    std::cout << "server start at: " << inet_ntoa(my_addr.sin_addr) << ':' << port << '\n';


    //listen 函數使伺服器開始監聽連接
    status = listen(sock_fd, 5);
    if (status == -1) {
        perror("Listening error");
        return -1;
    }

    
    int new_fd;
    socklen_t addrlen;
    sockaddr_in client_addr;
    addrlen = sizeof(client_addr);

    //accept 函數等待並接受一個客戶端連接,並返回新的套接字描述符,用於與客戶端通信。
    new_fd = accept(sock_fd, reinterpret_cast<struct sockaddr*>(&client_addr), &addrlen);

    return new_fd;
}



//此函數用來向已連接的客戶端發送數據。
int send_data_server(int client_fd, const char *data)
{
    return send(client_fd, data, strlen(data), 0);
}

//此函數用來從已連接的客戶端接收數據。
int receive_data_server(int client_fd, void *buffer, size_t buffer_size)
{
    return recv(client_fd, buffer, buffer_size, 0);
}

//此函數用來關閉與客戶端的連接。    
void closed_server(int client_fd)
{
    close(client_fd);
}