实现TCP服务器程序
第一步:调用socket 网络API,创建套接字文件
- socket函数
- int socket(int domain, int type, int protocol);
- 功能:创建一个套接字文件,然后文件形式来操作通信,不过套接字文件没有文件名。
- Linux有7种文件,套接字文件就是其中一种。
- socket翻译为中文就是“套接字”的意思,其实翻译为插座更合适些,因为socket本来就有插座的意思。
- 使用socket创建一个通信的套接字文件,就好比如插上了一个通信的插座,有了这个插座就可以和对方通信来。。。
- 返回值
- 成功:返回套接字描述符
- 参数:
- int socket(int domain, int type, int protocol)
- domain(族):
- 作用:指定协议族
- 为什么要指定协议族?
- 我们目前使用的是IPV4版本
- IPV4是Internet Protocol Version4的缩写。
- IPV4和IPV6所使用的地址格式完全不同?
- IPV4:ip为32位,IPV6:ip为64位
- domain可设置的常见宏值
- 可设置的有:AF_INET:IPV4因特网域
- type确定套接字类型,进一步确定通信特征。
- 套接字类型,说白了就是进一步指定,你想要使用协议族中的那个子协议来通信
- SOCK_STREAM:有序的、可靠的、双向的、面向连接的字节流
- 首先:将domain指定为AF_INET,表示使用的是IPV4的TCP/IP协议族
- 其次:对type进行相应设置,进一步表示想使用的TCP/IP协议族中的TCP协议
- type常见设置值:SOCK_STREAM
- SOCK_STREAM:
- 将type指定为SOCK_STREAM时,表示想使用的是“有序的、面向连接的、双向通信的、可靠的字节流通信”,这不就是TCP通信
- 将type指定为SOCK_DGRAM时,表示想使用的是“无连接、不可靠的、固定长度的数据报通信”,这不就是UDP通信
- protocol:指定协议号
- 一般情况下protocol写0
bind函数
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
- 功能:将指定了通信协议(TCP)的套接字文件与IP以及端口绑定起来。
- 注意:绑定的一定是自己的IP和端口,不是对方的,比如对于TCP服务器来说,绑定的就是服务器自己的ip和端口。
- 至于什么是绑定,为什么绑定,我们后面再详细解释。
- 返回值
- 成功返回0,失败-1,errno被设置。
- 参数
- sockfd:套接字文件描述符,表示socket创建的套接字文件。既然要绑定套接字文件、ip和端口,肯定要有一个东西来代表套接字文件。
- addrlen:第三个参数表示指定结构体的大小,写死。
- addr:struct sockaddr结构体变量的地址,结构体成员用于设置你要绑定的IP和端口。
-
结构体成员:
-
struct sockaddr { sa_family_t sa_family; char sa_data[14]; }
sa_family:指定AF_***,表示使用的什么协议族的IP,前面说过,协议族不同,ip格式就不同。这个类型的原型是unsigned short
sa_data :存放ip和端口 -
不过这样子写是不行的,如果ip和端口直接写入sa_data数组中,虽然可以做到,但是操作起来有点麻烦,不过好在,我们可以使用更容易操作的struct sockaddr_in结构体来设置
-
不过这个结构体手册没有描述,是下面这样的
-
struct sockaddr_in{ sa_family_t sin_family; //地址族 uint16_t sin_port; //端口号 struct in_addr sin_addr; //32位IP地址 char sin_zero; //预留未使用 }; struct in_addr{ In_addr_t s_addr; //32位IPv4地址 }; —————————————————————————————————————————————————————
-