C语言网络编程:accept函数详解

更新时间:2023-07-19 09:22:09 阅读: 评论:0

C语⾔⽹络编程:accept函数详解绿樱桃
⽂章⽬录
前⾔
当使⽤tcp服务器使⽤socket创建通信⽂件描述符,bind绑定了⽂件描述符,服务器ip和端⼝号,listen将服务器端的主动描述符转为被动描述符进⾏监听之后,接⼝accept通过三次握⼿与客户端建⽴连接
TCP 编程模型如下:
函数描述
#include <sys/socket.h>外国经典歌曲
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
函数功能:
被动监听客户端发起的tcp连接请求,三次握⼿后连接建⽴成功。客户端connect函数请求发起连接。
连接成功后服务器的tcp协议会记录客端的ip和端⼝,如果是跨⽹通信,记录ip的就是客户端所在路由器的公⽹ip
返回值:
成功:返回⼀个通信描述符,专门⽤于与连接成功的客户端进⾏通信。
失败:返回-1 ,并设置errno
函数参数:
戒烟好方法
a. sockfd 已经被listen转为了被动描述符的“套接字⽂件描述符”,专门⽤于客户端的监听,⼊股sockfs没有被listen函数转为被动描
述符,则accept是⽆法将其⽤来监听客户端连接的。
套接字⽂件描述符默认是阻塞的,即如果没有客户端请求连接的时候,此时accept会阻塞,直到有客户端连接;如果不想套接字⽂件描述符阻塞,则可以创建套接字 socket函数 时指定type为SOCK_NOBLOCK
b. addrlen表⽰第⼆个参数addr的⼤⼩,不顾要求给定地址
c. addr: ⽤于记录发起连接请求的那个客户端的IP端⼝
建⽴连接时服务器的TCP协议会⾃动解析客户端发来的数据包,从中获取客户端的IP和端⼝号
这⾥如果服务器应⽤层需要⽤到客户端的 IP和端⼝号,可以给accept指定第⼆个参数addr,以获取TCP链接时的客户端ip和端⼝号;如果服务器应⽤层不需要,则写NULL即可
addr的结构体类型为 struct sockaddr,在中我们有介绍过,由于这个结构体⽤起来不是⾮常⽅便,我们需要定义struct sockaddr_in结构体来使得sockaddr结构体操作更为便捷。具体使⽤如下:
struct sockaddr_in naddr ={0};
int nsize =sizeof(naddr);
练习使用显微镜int cfd =accept(sockfd,(struct sockaddr *)&naddr,&nsize);
陈继铭代码实例
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<sys/socket.h>项目管理组织机构
#include<sys/types.h>
#include<errno.h>
void print_err(char*str,int line,int err_no){
printf("%d, %s :%s\n",line,str,strerror(err_no));
_exit(-1);
}
int main()
{
int skfd =-1, ret =-1;
skfd =socket(AF_INET, SOCK_STREAM,0);
if(-1== skfd){
print_err("socket failed",__LINE__,errno);不做你的爱人
土豆焖面}
struct sockaddr_in addr;
addr.sin_family = AF_INET;//设置tcp协议族
addr.sin_port =6789;//设置端⼝号
addr.sin_addr.s_addr =inet_addr("192.168.102.169");//设置ip地址
ret =bind(skfd,(struct sockaddr*)&addr,sizeof(addr));
if(-1== ret){
print_err("bind failed",__LINE__,errno);
}
/*将套接字⽂件描述符从主动转为被动⽂件描述符,然后⽤于被动监听客户端的连接*/
ret =listen(skfd,3);
if(-1== ret ){
print_err("listen failed",__LINE__, errno);
}
/*被动监听客户端发起的tcp连接请求,三次握⼿后连接建⽴成功*/
int cfd =-1;
struct sockaddr_in caddr ={0};//为应⽤层获取客户端的IP和端⼝号
int csize =0;
cfd =accept(skfd,(struct sockaddr*)&caddr,&csize);
if(-1== cfd){
print_err("accept failed",__LINE__, errno);
}
return0;
}
如何得到客户端的IP 和端⼝号
⽐如程序中想要打印客户端的ip和端⼝号,这⾥就需要使⽤到ntohs和inet_ntoa函数进⾏端序转换,因为客户端的端⼝和ip是服务器的TCP 协议,从客户端发送端⽹络数据包中提取出来,⽹络数据包的端序属于⽹络端序,主机接收到数据后如果想要使⽤的话,就必须从⽹络端序转为主机端序。
举例如下:
struct sockaddr_in caddr ={0};
int csize =sizeof(caddr);
cfd =accept(sockfd,(struct sockaddr *)&caddr,&csize);
printf("cport = %d, caddr = %s\n",ntohs(caddr.sin_port),inet_ntoa(caddr.sin_addr));

本文发布于:2023-07-19 09:22:09,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/82/1104775.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:客户端   描述符   连接   结构   函数   被动   数据包   发起
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图