当电话响了,小明需要拿起电话机接受对方的连接请求,才能完成通话。网络通信道理相似,当有网络连接请求,需要调用相关函数接受连接,进行处理。
accept函数的Linux头文件以及函数定义如下:
#include <sys/types.h>
#include <sys/socket.h>
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
accept函数参数以及返回值如下:
/**
* 接受连接
*
* @param sockfd 上述listen函数指定的监听socket
* @param addr 请求连接方(即客户端)地址
* @param addrlen 客户端地址长度
* @return 函数执行成功返回一个新的连接socket,失败返回-1
*/
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
accept函数返回值:一个新的连接socket(因此也称为已连接套接字),该socket唯一标示了接受的新连接。后续双方可以利用已连接套接字进行通信。
下面可以在上述基础上,编写个测试accpet函数的程序,如下;
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <arpa/inet.h> // sockaddr_in
#include <sys/socket.h>
int main()
{
// 此处省略上一节重复代码
struct sockaddr_in client_addr;
socklen_t client_addr_len = sizeof(client_addr);
printf("等待连接中...\n");
int connfd = accept(server_socket, (struct sockaddr*)&client_addr, &client_addr_len);
if (connfd == -1) {
perror("accept error");
exit(1);
}
printf("accept ok\n");
return 0;
}
上述程序已经有了服务端的雏形,运行会发现,仅打印第14行——等待连接中,这是因为还没有客户端进行连接,因此accept函数发生了阻塞。
总结TCP服务端编写步骤,如下:调用socket函数创建套接字。
调用bind函数给创建的套接字命名,分配IP地址和端口。
调用listen函数进行监听,等待客户端连接。
调用accept函数接受新的连接,做好相互通信准备。
右侧打开accept_test.c文件,试添加accept函数,并编译测试。