1、编程模型函数化
函数学习
1)创建套接字
函数名:socket
函数原型:Int socket(int domain,int type,int protocol);
函数功能:创建套接字
所属头文件:<sys/types.h>、<sys/socket.h>
返回值:成功:返回对应于新套接字的文件描述符或者套接字的id,失败:返回错误编码
参数说明:domain:有一系列可取值;type:创建的套接字协议的类型;protocal:协议
解释:
int domain,表示套接字要使用的协议簇,协议簇在文件linux/socket.h有详细定义,常用的协议簇:
AF_UNIX(本机通信);
AF_INET(TCP/IP -IPv4);
AF_INET6(TCP/IP - IPv6);
其中type参数指的是套接字类型;常用的类型有:
SOCK_STREAM(TCP流);
SOCK_DGRAM(UDP数据报);
SOCK_RAW(原始套接字);
最后一个protocol一般设置为0,也就是当确定套接字使用的协议簇和类型时,这个参数的值就为0,但是有时候创建原始套接字时,并不知道要使用的协议簇和类型,也就是domain参数未知情况下,这时protocol这个参数就起作用了,它可以确定协议的种类。
socket是一个函数,那么它也有返回值,当套接字创建成功时,返回套接字,失败返回“-1”,错误代码则写入“errno”中。
2)绑定套接字
解释:Socket套接字地址:是一个数据结构,基于TCP传输协议为例,其数据结构里面包含了:
例子:
对于
对于选项INADDR_ANY,就是指的是0.0.0.0的地址,表示所有地址,任意地址,用于一台电脑上有多个网卡的情况,方便管理,管理一个套接字就行,不管数据从哪个网卡过来,只要是绑定的端口号过来的数据,都可以接收;而客户端不能使用INADDR_ANY选项;htons #include <arpa/inet.h>
uint16_t htons(uint16_t hostshort);
功能: 将一个无符号短整型数值转换为网络字节序,即大端模式(big-endian)
htons 是把你机器上的整数转换成“网络字节序”, 网络字节序是 big-endian,也就是整数的高位字节存放在内存的低地址处。而我们常用的 x86 CPU (intel, AMD) 电脑是 little-endian,也就是整数的低位字节放在内存的低字节处。
举个例子:假定你的port是 0x1234, 在网络字节序里 这个port放到内存中就应该显示成 addr addr+1 0x12 0x34 而在x86电脑上,0x1234放到内存中实际是: addr addr+1 0x34 0x12 htons 的用处就是把实际内存中的整数存放方式调整成“网络字节序”的方式。
htonl() #include <arpa/inet.h>
功能:将主机的无符号长整形数转换成网络字节顺序。
uint32_t htonl(uint32_t hostlong);
inet_addr() 将一个字符串格式的ip地址转换成一个uint32_t数字格式,但是需要注意的是, 这个函数的返回值在大小端机器上是不同的;
例如输入一个"192.168.0.1"的字符串, 在内存中的排列(字节从低到高) 0xC0, 0xA8 ,0x00 ,0x4A。 那么在小端序机器上,返回的数字就是0x4a00a8c0 , 而在大端序机器上则是0xc0a8004a
函数名:bind
函数原型:Int Bind(int sockfd,const struct sockaddr *addr,socklen_t addrlen);
函数功能:绑定套接字:将ip地址与套接字相绑定
所属头文件:<sys/types.h>、<sys/socket.h>
返回值:成功:返回对应于新套接字的文件描述符或者套接字的id;失败:返回错误编码
参数说明:sockfd:要绑定套接字的fd;addr:将套接字与那个地址进行绑定;addrlen:地址长度
网络字节序:
3)监听
作用:1、用来指明服务器已经做好了准备,可以用来接收客户机的请求了。2、用来设置服务器可以接受多少个客户机的连接请求
参数:sockfd与之关联的套接字的fd。Backlog:客户机的数目,即允许多少个客户机来进行连接。
成功:返回0,失败:返回-1
4)等待连接
作用:等待客户机来进行连接,如果无客户机来连接,则导致服务器在这里阻塞。
参数:sockfd:创建的套接字的fd。Addr:如果有客户机来进行连接,那么通过本地址来返回客户机的地址。Len:接收到客户机的地址的长度
成功:返回新的套接字的描述符。后面在发送和接收数据时用这个新的fd来进行操作。
5)发送数据
函数名:Send
ssize_t send(int sockfd,const void *buf,size_t nbytes,int flags);
作用:发送数据
参数:sockfd:新的套接字的fd,buf:要发送数据的地址,nbytes:要发送数据的长度,flags:标志
6)接收数据
参数:sockfd:新的套接字的fd,buf:要存数据的地址,nbytes:希望接收多大量的数据,flags:标志
7)关闭连接
Close
8)连接服务器
参数:新创建的套接字的fd,addr:保存的服务器的地址,len:服务器地址的长度
成功:返回0
失败:返回-1
9)
返回值:若成功则为1,若输入不是有效的表达式则为0,若出错则为-1
返回值:若成功则为指向结构的指针,若出错则为NULL
tcp_server.c
修改:
tcp_client.c