面试题答案
一键面试bind函数参数及其含义
bind
函数用于将一个套接字与一个地址绑定。其原型为:
#include <sys/types.h>
#include <sys/socket.h>
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
- sockfd:
- 含义:要绑定地址的套接字描述符。这是通过
socket
函数创建的套接字。
- 含义:要绑定地址的套接字描述符。这是通过
- addr:
- 含义:指向要绑定的地址结构的指针。对于IPv4,这个结构是
struct sockaddr_in
,对于IPv6是struct sockaddr_in6
。在实际使用中,通常会先填充对应的IPv4或IPv6地址结构,然后将其强制转换为struct sockaddr *
类型。 - 以IPv4为例,
struct sockaddr_in
的常见填充方式:
- 含义:指向要绑定的地址结构的指针。对于IPv4,这个结构是
struct sockaddr_in servaddr;
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(SERVER_PORT);
servaddr.sin_addr.s_addr = INADDR_ANY; // 或指定具体IP地址,如inet_addr("192.168.1.100")
- addrlen:
- 含义:地址结构的长度。对于
struct sockaddr_in
,其长度为sizeof(struct sockaddr_in)
;对于struct sockaddr_in6
,长度为sizeof(struct sockaddr_in6)
。
- 含义:地址结构的长度。对于
简单代码示例
以下是一个简单的基于IPv4的TCP服务器端代码示例,展示如何使用bind
函数:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#define SERVER_PORT 8888
#define MAXLINE 1024
int main() {
int listenfd, connfd;
struct sockaddr_in servaddr;
char buff[MAXLINE];
int n;
// 创建套接字
listenfd = socket(AF_INET, SOCK_STREAM, 0);
if (listenfd < 0) {
perror("socket error");
exit(1);
}
// 填充服务器地址结构
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(SERVER_PORT);
// 绑定套接字到指定地址和端口
if (bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0) {
perror("bind error");
close(listenfd);
exit(1);
}
// 监听套接字
if (listen(listenfd, 10) < 0) {
perror("listen error");
close(listenfd);
exit(1);
}
printf("Server is listening on port %d...\n", SERVER_PORT);
// 接受客户端连接
connfd = accept(listenfd, (struct sockaddr *)NULL, NULL);
if (connfd < 0) {
perror("accept error");
close(listenfd);
exit(1);
}
// 与客户端通信
n = read(connfd, buff, MAXLINE);
buff[n] = '\0';
printf("Received from client: %s\n", buff);
// 发送响应给客户端
char *response = "Hello, client!";
write(connfd, response, strlen(response));
// 关闭套接字
close(connfd);
close(listenfd);
return 0;
}
在上述代码中,首先创建了一个TCP套接字listenfd
,然后填充struct sockaddr_in
结构servaddr
,设置其协议族为IPv4(AF_INET
),地址为INADDR_ANY
(表示接受任何本地IP地址的连接),端口号为SERVER_PORT
(8888)。接着使用bind
函数将listenfd
绑定到servaddr
指定的地址和端口。之后进入监听和接受连接的流程,与客户端进行简单的通信。