linux服务器开发-网络编程-套接字

一. socket套接字
1.1 网络字节序

#include <arpa/inet.h>
int inet_pton(int af, const char *src, void *dst);

inet_pton:将“点分十进制” -> “二进制整数”
int inet_pton(int af, const char src, void dst);
这个函数转换字符串到网络地址,第一个参数af是地址簇,第二个参数
src是来源地址,第三个参数
dst接收转换后的数据。
inet_pton 是inet_addr的扩展,支持的多地址族有下列:
af = AF_INET
src为指向字符型的地址,即ASCII的地址的首地址(ddd.ddd.ddd.ddd格式的),函数将该地址转换为in_addr的结构体,并复制在dst中。
af = AF_INET6
src为指向IPV6的地址,函数将该地址转换为in6_addr的结构体,并复制在
dst中。
如果函数出错将返回一个负值,并将errno设置为EAFNOSUPPORT,如果参数af指定的地址族和src格式不对,函数将返回0。
示例如下:


       #include <arpa/inet.h>
       #include <stdio.h>
       #include <stdlib.h>
       #include <string.h>

       int
       main(int argc, char *argv[])
       {
           unsigned char buf[sizeof(struct in6_addr)];
           int domain, s;
           char str[INET6_ADDRSTRLEN];

           if (argc != 3) {
               fprintf(stderr, "Usage: %s {i4|i6|<num>} string\n", argv[0]);
               exit(EXIT_FAILURE);
           }

           domain = (strcmp(argv[1], "i4") == 0) ? AF_INET :
                    (strcmp(argv[1], "i6") == 0) ? AF_INET6 : atoi(argv[1]);

           s = inet_pton(domain, argv[2], buf);
           if (s <= 0) {
               if (s == 0)
                   fprintf(stderr, "Not in presentation format");
               else
                   perror("inet_pton");
               exit(EXIT_FAILURE);
           }

           if (inet_ntop(domain, buf, str, INET6_ADDRSTRLEN) == NULL) {
               perror("inet_ntop");
               exit(EXIT_FAILURE);
           }

           printf("%s\n", str);

           exit(EXIT_SUCCESS);
       }

1.2 socket函数

#include <sys/types.h>          /* See NOTES */
 #include <sys/socket.h>
  int socket(int domain, int type, int protocol);

af:一个地址描述。仅支持AF_INET格式,也就是说ARPA Internet地址格式。
type:指定socket类型。新套接口的类型描述类型,如TCP(SOCK_STREAM)和UDP(SOCK_DGRAM)。常用的socket类型有,SOCK_STREAM、SOCK_DGRAM、SOCK_RAW、SOCK_PACKET、SOCK_SEQPACKET等等。
protocol:顾名思义,就是指定协议。套接口所用的协议。如调用者不想指定,可用0。常用的协议有,IPPROTO_TCP、IPPROTO_UDP、IPPROTO_STCP、IPPROTO_TIPC等,它们分别对应TCP传输协议、UDP传输协议、STCP传输协议、TIPC传输协议。

1.3 bind函数
#include <sys/types.h>
#include <sys/socket.h>
int bind(int sockfd,const struct sockaddr *addr,socklen_t addrlen);
sockfd:socket文件描述符
addr:构造出IP地址加端口号
addrlen:sizeof(addr)长度
返回值:成功返回0,失败返回-1,设置errno。

1.4 listen函数

#include <sys/types.h>
#include <sys/socket.h>
int listen(int sockfd,int backlog);

sockfd:socket文件描述符
backlog:排队建立3次握手队列和刚刚建立3次握手队列的连接数和

查看系统默认backlog
cat /proc/sys/net/ipv4/tcp_max_syn_backlog

典型的服务器程序可以同时服务于多个客户端,当有客户端发起连接时,服务器调用的accept()返回并接受这个链接,如果有大量的客户端发起链接而服务器来不及处理,尚未accept的客户端就处于链接等待状态,listen()声明sockfd处于监听状态,并且最多允许有backlog个客户端处于链接等待状态,如果接受到更多的连接请求就忽略,listen()成功返回0,失败返回-1.

1.5 accept函数

#include <sys/types.h>
#include <sys/socket.h>
int accept(int sockfd,struct sockaddr *addr,socklen_t *addrlen);
sockfd:文件描述符
addr:传输参数,返回连接客户端地址信息,含IP地址和端口号
addrlen:传入传出参数(-结果),传入sizeof(addr)大小,函数返回时返回真正接收到地址结构体的大小
返回值:成功返回一个新的socket文件描述符,用于和客户端通信,失败返回-1,设置errno。

三方握手成功后,服务器调用accept()接受连接,如果服务器调用accept()时还没有客户端的连接请求,就阻塞等待直到有客户端连接上来,addr是一个传出参数,accept()返回时传出客户端的地址和端口号,addrlen参数是一个传入传出参数,传入的是调用者提供的缓冲区addr的长度以避免缓冲区出问题,传出的是客户端地址结构体的实际长度(有可能没有占满调用者提供的缓冲区),如果给addr参数传null,表示不关心客户端的地址。

1.6 connect函数

#include <sys/types.h>
#include <sys/socket.h>
int connect(int sockfd,const struct sockaddr *addr,socklen_t addrlen);
sockfd:socket文件描述符
addr:传入参数,指定服务器端地址信息,含IP地址和端口号
addrlen:传入参数,传入sizeof(addr)大小
返回值:成功返回0,失败返回-1,设置errno

客户端需要调用connect()连接服务器,connect和bind的参数形式一致,区别在于bind的参数是自己的地址,而connect的参数是对方的地址,connect()成功返回0,出错返回-1.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值