套接字API

本文介绍了socket编程的基本概念,包括socket创建、绑定、监听等关键步骤,并解释了不同类型的socket及网络字节序转换。

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

1>

int socket(int domain, int type, int protocol);//domain: 网络层   type:传输层  

domain:
AF_INET 这是大多数用来产生socket的协议,使用TCP或UDP来传输,用IPv4的地址
AF_INET6 与上面类似,不过是来用IPv6的地址
AF_UNIX 本地协议,使用在Unix和Linux系统上,一般都是当客户端和服务器在同一台及其上的时候使用
type:
SOCK_STREAM 这个协议是按照顺序的、可靠的、数据完整的基于字节流的连接。这是一个使用最多的socket类
型,这个socket是使用TCP来进行传输。
SOCK_DGRAM 这个协议是无连接的、固定长度的传输调用。该协议是不可靠的,使用UDP来进行它的连接。
SOCK_SEQPACKET 这个协议是双线路的、可靠的连接,发送固定长度的数据包进行传输。必须把这个包完整的
接受才能进行读取。
SOCK_RAW 这个socket类型提供单一的网络访问,这个socket类型使用ICMP公共协议。(ping、traceroute使
用该协议)
SOCK_RDM 这个类型是很少使用的,在大部分的操作系统上没有实现,它是提供给数据链路层使用,不保证数
据包的顺序
protocol:
0 默认协议
返回值:
成功返回一个新的文件描述符,失败返回-1,设置errno


2>

      这个函数将端口与套接字绑定在一起,那么别人就可以明确的知道我的固定的ip+端口这样便可以访问我


int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);


sockfd:socket文件描述符
addr:    构造出IP地址加端口号
addrlen:   sizeof(addr)长度


返回值:成功返回0,失败返回-1, 设置errno


struct sockaddr_in servaddr;
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;//使用ipv4
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);//任何人都可以链接我
servaddr.sin_port = htons(8000);  //绑定端口8000


        struct sockaddr 结构是比较早的结构可能比 IPV4还要先有  其实这个结构已经不常用  只是为了兼容 然而和struct sockaddr_in一样还有很多结构

他们的前16位是相同的  所以可以把这个结构地址作为参数传递给bind(做强制转换)

         虽然接口一直没变,但是函数体内部一直在变。这就体现了头文件+库的好处


3>网络字节序 

      字节序有大端和小端,而网络字节序可能与计算机字节序不一样所以需要转换。(注意这里是字节序)

     小端:高地址  高位

     大端:高地址  低位    //网络字节序为大端

     这些转换的api

       uint32_t htonl(uint32_t hostlong);


       uint16_t htons(uint16_t hostshort);


       uint32_t ntohl(uint32_t netlong);


       uint16_t ntohs(uint16_t netshort);


       h:host 主机    n:net 网络    l:32位IP地址   s:16位端口号

       IP地址与端口号会封装在数据包里而处理这些数据包的设备  网卡  路由器.....是按照网络字节序处理所以字节序不一样可能把ip和端口号搞错


       const char *inet_ntop(int af, const void *src,char *dst, socklen_t size);//将网络地址转换成字符串

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

       af:必须是AF_INET or AF_INET6

       void *:为指向地址的指针

       char*:指向的缓冲区被填充 或 作为值转换成数值地址

      

4>

        赋予socket套接字,监听能力。把主动套接字转换成被动套接字。指示内核应该接受指向这个套接字的连接。

int listen(int sockfd, int backlog);


sockfd: socket文件描述符
backlog = 未完成队列 + 已完成队列 (redhat最大数量为1024)//不要把它设置为零  这样可能是不确定的

cat /proc/sys/net/ipv4/tcp_max_syn_backlog  命令可以查看linux内核支持的最大队列  要是backlog超过这个数量 也没有用 最多就这么多个


根据unp1  内核为监听套接字维护两个队列:

未完成连接队列:SYN分节已经到达  但还未完成三次握手  如果完成添加到已完成队列

已完成连接队列:已经完成三次握手

三次握手的过程由内核自己完成  我们不必操心


5>

        这个函数从已完成队列头中取出一个连接,如果队列为空那么函数陷入睡眠。

int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen); //后两个参数如果不感兴趣可以设置成NULL


sockdf:  socket文件描述符
addr:  传出参数,返回链接客户端地址信息,含IP地址和端口号
addrlen:  传入传出参数(值-结果),传入sizeof(addr)大小,函数返回时返回真正接收到地址结构体的大小


返回值:成功返回一个新的socket文件描述符,用于和客户端通信,失败返回-1,设置errno


6>

  用于连接服务器的监听套接字,建立TCP连接。三路握手成功或出错时返回。

int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);


sockdf:  socket文件描述符
addr:  传入参数,指定服务器端地址信息,含IP地址和端口号
addrlen:  传入参数,传入sizeof(addr)大小
返回值:成功返回0,失败返回-1,设置errno



7>

close()用于关闭连接  因为套接字也是文件描述符来表示的吗




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值