网络编程——listen、conect、inet_pton等网络编程函数详解

前言
自己在学习网络编程的所思所感所悟,记录于此,如果还有幸能帮助到您,是我的荣幸!很多网络编程的函数都没有见过也忘记了他的头文件,怎么办?在linux上使用man手册查函数即可,windows查msdn。在linux有时候用man手册查函数,可能出来的并不是函数,而是一个命令,比如你查bind函数,在shell上打出man bind出现的是命令不是函数,别急,输入man 2 bind就可以出来你想要的函数了。man手册查函数

connect函数

返回错误的情况
一般来说,服务器都是被动打开的,客户端是主动连接的,connect相当于主动连接的函数。这里如果没有想出来可以画画TCP三次握手,看看是哪一端先发送的SYN。想让客户端来找服务器端,而不是让服务器去找客户端。
(1)超时连接,客户端没有收到服务器发来的SYN(TCP第二次握手服务器向客服端发送的SYN),过一会再向服务器发送一个SYN(再次请求连接服务器,TCP第一次握手,客户端发送SYN给服务器),超过一定的时间返回错误。
(2)无效的端口,客户端连接的服务器主机,服务器主机并没有监听那个端口,对服务器发来的SYN响应是RST。
(3)客户端在某一个路由已发目的地不可达ICMP错误(我还没有遇到过这种情况)

bind函数

(目前理解的还不是很深)
一般客户端连接服务器,会由内核创建一个临时端口号给客户端连接,返回值0表示成功,-1表示失败

listen函数

listen(int sockfd,int backlog);成功返回0失败返回-1
内核帮我们监听两个队列,一个是已完成的连接队列,一个是等待连接的队列,看下面的TCP换图,当等待连接的时候是在左侧的SYN_RCVD状态下等待监听,当三次握手完成后就进入已完成的连接队列,并且状态变为ESTABLISHED,等待着被accept

在这里插入图片描述
listen函数第二个参数
未完成队列的数量(最大排队的数量),以前是设置5(实际上的数量会略大于设置的值),当未完成队列中等待的数量已经达到最大的限度的时候,会忽略想排队的套接字,但是不返回RST(用来异常关闭的),毕竟这是暂时的不是错误。(忽略该套接字,客户端过一会还是会重新发送SYN,所以队列满了忽略也没什么问题)。有时候网站访问的人多就打不开,我怀疑跟这个因素有关,不能及时处理队列中的握手请求,打开的慢(估计一直在重传),404了(估计重传超时了,放弃重传了)

TCP四次挥手服务器发送的ACK为什么不可以像TCP三次握手服务器发送的ACK一样是被稍带的呢?

TCP三次握手,服务器被动打开,像客户端发送的ACK是因为要向客户端发送SYN才顺带发送的。
写在这里的时候突然在想为什么四次挥手服务器收到客户端发送的FIN返回的ACK不可以像三次握手一样ACK顺带发过去的(服务器给客户端发送SYN的时候顺便带上的ACK),看了篇文章大概知道了,当客户端发送了FIN,服务器发送ACK表示收到了关闭请求,但还是要查看还有没有要发给客服端的消息,没有的话在发送FIN给客户端。参考的文章链接

UDP服务器需要使用listen函数吗

对于UDP的服务器需要listen吗?思考一下。
答案是不需要listen监听,listen监听的是TCP三次握手,UDP又没有三次握手,肯定不需要listen呀,当然UDP更不需要accept,accept是TCP三次握手完了之后再创建的连接

inet_pton函数

网络编程提供的新函数函数原型,函数名字解释,inet_标准的头了,后面的意思是presentation(表达) to numeric(数值),将你的表达式转换成二进制

int inet_pton(int af, const char *src, void *dst);

如用的方法如下

sockaddr_in addr;
        addr.sin_family =AF_INET;
        addr.sin_port = htons(port);
        inet_pton(AF_INET,"127.0.0.1",&addr.sin_addr);//绑定一下IP地址

inet_ntop函数

名字和上面的是一样的,只不过是从二进制转换成IP地址。

const char *inet_ntop(int af, const void *src,
                             char *dst, socklen_t size);

函数用法如下:该函数也不需要保存返回值,因为已经保存到第三个参数里面了。INET_ADDRSTRLEN是定义好的,大小为16,这里一定要记住哦,str一定要数组的形式,不可以用指针,inet_ntop函数里面用到了strcpy,strcpy就是不允许一个字符串给野指针拷贝,如果就想用char* str,记得要给他new一下,同时别忘记了delete str。尽管当你程序结束了,操作系统会回收给你的进程分配的空间没有内存泄露,但养成好的习惯我觉得还是蛮有必要的!

char str[INET_ADDRSTRLEN];
                inet_ntop(AF_INET,&client.sin_addr,str,sizeof(str));

shutdown函数

客户端如果调用shutdown函数,会发送给服务器一个FIN,服务器回一个ACK(半关闭状态), int shutdown(int sockfd, int how)跟第二个参数有关,SHUT_RD客户端这个套接字不再接收数据,SHUT_WR把套接字缓冲区的数据全部发送出去(主要是怕还有数据未发送就关闭了,所以用一下shutdown)。最后在配合close函数关闭。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值