服务端编程
C/S模型
- 服务端:长期暴露在网络中,等待客户端的连接;
- 客户端:发起连接动作,并等待服务端的回应;
- 特点:
1、服务端无法主动连接客户端;
2、客户端只能按照预定义的方式连接服务端;
服务端编程模式
- 流程:准备网路连接 --> 绑定端口 --> 进入端口监听状态 --> 等待连接;
服务器核心工作
- 绑定:int bind(int sock,struct sockaddr* addr /* ip地址+端口号*/,socklen_t addrlen);
- 监听:int listen(int sock,int backlog /* 队列长度 */);
- 接收:int accept(int sock,struct sockaddr* addr,socklen_t* addrlen);/* return:与客户端通信的socket* /
深度刨析服务端
- 服务端socket只能用于接收连接,不进行实际通信;
- 当接收到连接时,accept()函数返回与客户端通信的socket
- 服务端socket产生用于通信的客户端socket
深入理解socket()函数
- 功能:提供互联网、专用网络及本地进程间通信能力的多功能函数;
- 返回值:用于通信的资源标识符(标识通信中所占用的资源,最后要用close函数释放);
服务端编程示例
int server = 0;
struct sockaddr_in saddr = {0};
int client = 0;
struct sockaddr_in caddr = {0};
socklen_t asize = 0;
int len = 0;
char buf[32] = {0};
int r = 0;
server = socket(PF_INET,SOCK_STREAM,0);
if(server == -1){
printf("server socket error");
return -1;
}
saddr.sin_family = AF_INET;
saddr.sin_addr.s_addr = htonl(INADDR_ANY);
saddr.sin_port = htons(8899);
if( bind(server,(struct sockaddr*)&saddr,sizeof(saddr)) == -1){
printf("server bind error\n");
return -1;
}
if( listen(server,1) == -1 ){
printf("server listen error \n");
return -1;
}
printf("server listen success\n");
asize = sizeof(caddr);
client = accept(server, (struct sockaddr*)&caddr, &asize);
if( client == -1 ){
printf("client accept error\n");
return -1;
}
printf("client:%d\n",client);
len = 0;
do
{
int i = 0;
r = recv(client,buf,sizeof(buf),0);
if(r > 0)
{
len += r;
}
for(i = 0; i < r; i++)
{
printf("%c",buf[i]);
}
}while(len < 64)
printf("\n");
send(client, "Hello world!",12,0);
sleep(1);
close(client);
close(server);
return 0;
C/S核心模式
- 服务端长时间运行(死循环)接收客户端的请求;
- 客户端主动向服务端发送请求(协议数据);