接受阻塞套接字上的連線
希望接受網路連線(充當伺服器)的 AC 程式應首先建立一個繫結到地址“INADDR_ANY”的套接字,並在其上呼叫 listen
。然後,它可以呼叫伺服器套接字上的 accept
來阻止,直到客戶端連線。
//Create the server socket
int servsock = socket(AF_INET, SOCK_STREAM, 0);
if(servsock < 0) perror("Failed to create a socket");
int enable = 1;
setsockopt(servsock, SOL_SOCKET, SO_REUSEADDR, (char*)&enable, sizeof(int));
//Bind to "any" address with a specific port to listen on that port
int port = 12345;
sockaddr_in serv_addr;
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(port);
if(bind(servsock, (sockaddr*)&serv_addr, sizeof(serv_addr)) < 0)
perror("Error binding to socket");
listen(servsock, 5);
//Accept a client
struct sockaddr_storage client_addr_info;
socklen_t len = sizeof client_addr_info;
int clientsock = accept(servsock, (struct sockaddr*)&client_addr_info, &len);
//Now you can call read, write, etc. on the client socket
傳遞給 accept
的 sockaddr_storage
結構可用於檢索有關連線的客戶端的資訊。例如,以下是如何確定客戶端的 IP 地址:
char client_ip_str[INET6_ADDRSTRLEN + 1];
if(client_addr_info.ss_family == AF_INET) {
// Client has an IPv4 address
struct sockaddr_in *s = (struct sockaddr_in *)&client_addr_info;
inet_ntop(AF_INET, &s->sin_addr, client_ip_str, sizeof(client_ip_str));
} else { // AF_INET6
// Client has an IPv6 address
struct sockaddr_in6 *s = (struct sockaddr_in6 *)&client_addr_info;
inet_ntop(AF_INET6, &s->sin6_addr, client_ip_str, sizeof(client_ip_str));
}