Untitled
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); }