《UNIX网络编程》卷一第四章学习笔记

本文详述了《UNIX网络编程》卷一第四章的关键内容,包括socket、connect、bind、listen、accept等函数的使用及作用。重点讨论了服务器如何从监听套接字到建立连接的过程,同时提及并发服务器的实现和getsockname、getpeername函数的应用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

《UNIX网络编程》卷一第四章学习笔记

  • 4.2 socket函数
#include<sys/socket.h>
int socket(int family,int type,int protocol);
//返回值:出错返回-1,否则返回非负描述符

 famliy参数指明协议族:

取值含义
AF_INETIPV4协议
AF_INET6IPV6协议
AF_LOCALUnix域协议
AF_ROUTE路由套接字
AF_KEY密钥套接字

 type参数指明套接字类型:

取值含义
SOCK_STREAM字节流套接字
SOCK_DGRAM数据报套接字
SOCK_SEQPACKET有序分组套接字
SOCK_RAW原始套接字

 protocol参数指定传输协议:

取值含义
IPPROTO_TCPTCP传输协议
IPPROTO_UDPUDP传输协议
IPPROTO_SCTPSCTP传输协议
0给定famliy和type组合的系统默认值
  • 4.3 connect函数
#include<sys/socket.h>
int connect(int sockfd,const struct sockaddr *servaddr,socklen_t addrlen);
//返回值 成功返回0,出错返回-1

 sockfd是由socket函数返回的套接字描述符,后两个参数分别是一个指向套接字地址结构的指针和该结构的大小。套接字地址结构必须含有服务器的IP地址和端口号。

  • 4.4 bind函数
#include<sys/socket.h>
int bind(int sockfd,const struct sockaddr *myaddr,socklen_t addrlen);
//返回值 成功返回0,出错返回-1

 bind函数把一个本地协议赋予一个套接字。参数和connect是一样的,但后两个可以都指定,也可以指定一个,也可以不指定。不指定的参数由内核进行配置。

  • 4.5 listen函数
#include<sys/socket.h>
int listen(int sockfd,int backlog);
//成功返回0,出错返回-1

 listen函数仅由TCP服务器调用,它做两件事情。
1)当socket函数创建一个套接字时,它被假设为一个主动套接字,也就是说,它是一个将调用connect发起连接的客户套接字。listen函数把一个未连接的套接字转换成一个被动套接字,指示内核应接受指向该套接字的连接请求。
2)listen函数第二个参数规定了内核应为相应套接字排队的最大连接个数(也许实际会更大一些)。
 本函数通常在socket和bind后accept前被调用。

  • 4.6 accept函数
     accept函数由TCP服务器调用,用于从已完成连接对楼队头返回下一个已完成连接。如果已连接队列为空,那么进程被置于休眠状态。
#include<sys/socket.h>
int accept(int sockfd,struct sockaddr *cliaddr,socklen_t *addrlen);
//成功返回非负描述符,出错返回-1

 addrlen是值-结果参数:调用前将指针对应值为cliaddr地址结构的长度,返回时,指针对应值被修改为内核存放在该套接字地址结构内的确切字节数。
 要区分accept函数返回的已连接套接字描述符和它的第一个参数监听套接字描述符。一个服务器通常仅仅创建一个监听套接字,它在该服务器的生命期内一直存在。内核为每个由服务器进程接受的客户连接创建一个已连接套接字,当服务器完成对某个给定用户的服务时,相应的已连接套接字就被关闭。
 如果对连接者的IP、端口号不感兴趣,accept函数的后两个参数可置为NULL。但好像不能只设置一个,否则会有一些问题。

  • 4.7 fork和exec函数
     这两个其实和网络编程没太大关系。前者比较重要的一点是父进程中调用fork前打开的所有描述符在fork返回后由子进程分享。后者不是很熟悉,手写shell才会用到吧……
  • 4.8 并发服务器
     举了个简单的并发例子。没有啥。
  • 4.9 close函数
    close函数在文件就涉及到,也没啥。
#include<unistd.h>
int close(int sockfd);
//成功返回0,出错返回-1
  • 4.10 getsockname和getpeername函数
     这两个函数或返回与某个套接字关联的本地协议地址,或返回与某个套接字相关的外地协议地址。
#include<sys/socket.h>
int getsockname(int sockfd,struct sockaddr *localaddr,socklen_t *addrlen);
int getpeername(int sockfd,struct sockaddr *peeraddr,socklen_t *addrlen);
//成功返回0,出错返回-1

 通俗地讲,这两个函数的作用就是就是在第二个参数指向的套接字地址结构中填充本机IP地、址服务器进程所用端口号和地址族。顾名思义,getsockname自然就是返回自己这边的地址结构,getpeername则是返回对面的。
 第一个函数,我觉得似乎没啥用……不过数组书中给出了getpeername的应用场景,看后觉得很有道理,复述如下:

 当一个服务器是由调用1过accept的某个进程通过调用exec执行程序时,它能够获取客户身份的唯一途径便是调用getpeername。inetd fork并exec某个TCP服务器程序时就是如此情形。……inetd随后调用fork,派生除inetd的一个子进程。既然子进程起始于父进程内存镜像的一个副本,父进程中的那个套接字地质结构在子进程中也可用,那个已连接的描述符也是如此。然而当子进程调用exec执行真正的服务器程序时,子进程的内存映像被替换成新的服务器程序文件(也就是说包含对端地址的那个套接字地址结构就此丢失),不过那个已连接套接字描述符跨exec继续保持开放。服务器程序首先调用的函数之一便是getpeername,用于获取用户的IP地址和端口号。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值