Untitled
unknown
plain_text
2 years ago
2.6 kB
12
Indexable
#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);
}Editor is loading...