Linux学习——TCP
一.TCP编程API

1.socket函数
1.socket函数
 include include
 int socket(int domain,int type,int protocol);
     参数
         domain
         AF_INET
         AF_INET6
         AF_UNIX,AF_LOCAL
         AF_NETLINK
         AF_PACKET
     type
         SOCK_STREAM: 流式套接字,唯一对应于TCP
         SOCK_DGRAM:数据报套接字,唯一对应着UDP
         SOCK_RAW:原始套接字
     protocol
         一般填0,原始套接字编程时需填充
     返回值
         成功返回文件描述符
         出错返回-1
         如果是IPV6编程,要使用struct sockddr_in6结构体(man 7 IPV6),通常使用struct                        
         sockaddr_storage来编程。
2.bind函数
2.bind函数
 int bind(int sockfd,const struct sockaddr *addr,socklen_t addrlen)
     参数
         sockfd:通过socket()函数拿到的fd
         addr:采用struct sockaddr的结构体地址,通用结构体
         struct sockaddr
          {
             sa_family_t sa_family;
             char sa_data[4];
          }
         struct sockaddr_in{ 基于Internel通信结构体
             as_family_t sin_family;
             in_port_t sin_port;
             struct in_addr sin_addr;
             sin_zero , //填充字节,需清零
             }
         struct in_addr{
             uint32_t s_addr;
             }
         addrlen:地址长度
3.listen函数
3.listen()函数
 int listen(int sockfd,int backlog);
     参数:
         sockfd: 通过socket()函数拿到的fd;
         backLog:同时允许几路客户端和服务器进行正在连接的过程(正在三次握手),一般填5。
             内核中服务器的套接字fd会维护2个链表
                 1.正在三次握手的客户端链表(数量=2*backlog+1)
                 2.已经建立好连接的客户端链表(已经完成三次握手分配好了的newfd)
         返回值:
                 成功返回0
             出错返回-1
     listen(fd,5);//表示系统允许11(2*5+1)个客户端同时进行三次握手
3.listen()函数
int listen(int sockfd,int backlog);参数:sockfd: 通过socket()函数拿到的fd;backLog:同时允许几路客户端和服务器进行正在连接的过程(正在三次握手),一般填5。内核中服务器的套接字fd会维护2个链表1.正在三次握手的客户端链表(数量=2*backlog+1)2.已经建立好连接的客户端链表(已经完成三次握手分配好了的newfd)返回值:成功返回0出错返回-1listen(fd,5);//表示系统允许11(2*5+1)个客户端同时进行三次握手 
4.accept函数
4.accept()函数
阻塞等待客户端连接请求int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);参数sockfd:经过前面socket()创建并通过bind(),listen()设置过的fdaddr:指向存放地址信息的结构体的首地址获取客户端IP地址和端口号addrlen:存放地址信息的结构体的大小返回值成功,返回返回已经建立连接的新的newfd出错,返回-1 
5.客户端连接函数connect
5.客户端连接函数connect()
int connect (int sockfd, struct sockaddr * serv_addr, int addrlen)参数:sockfd:通过socket()函数拿到的fdaddr:struct sockaddr的结构体变量地址addrlen:地址长度返回值:成功,返回0失败,返回-1 
二.编程
socket函数编写
用将socket函数的返回值给fd,通过fd是否小于零来判断是否成功

bland函数
第一个参数是socket()拿到的fd
sockaddr_in 结构体
第二个参数是结构体,需先定义 sockaddr_in 结构体
定义之后在填充之前还需要将结构体清零 ,用bzero函数清零

清零之后去初始化结构体
man 2 bind 往下滑找到 socket,它是在man 7 ip,去man 7 ip 中找到我们填充的sockaddr_in结构体,发现它初始化用的是AF_INET



初始化之后去写结构体的第二个参数sin_port的ip地址,可以去宏定义,5000以前是内核相关的,为了防止冲突写5001

SERV_IP_ADDR通过ifconfig查看

sin_port用的是本地字节,需要转换成网络字节,用u_short htons(u_short short)主机字节序到网络字节序

结构体第三个参数
sin_addr 又指向s_addr,也是要转换成网络节字


sockaddr_in结构体也可以使用另一种方式初始化与配置


将sockaddr_in结构体转化成sockaddr结构体

bind函数成功返回0,失败返回-1
去判断是否成功

