(一) CS模型
也就是TCP的客户/服务器模型,我们这里用一个简单的回射客户/服务器模型来进行模拟验证。客户发送数据,服务器接收到数据,并将数据原封不动的返回给客户端。
(二)用到的函数
1.socket()函数
1)函数原型:
int socket(int domain, int type, int protocol);
2)功能:
创建一个套接字用于通信。
3)参数:
1.domain:即协议域,又称为协议族(family):
2.type:指定socket类型:常用的socket类型有,SOCK_STREAM(流式套接字)、SOCK_DGRAM(数据包套接字)。
3.protocol:公共协议;
常用的公共协议有,IPPROTO_TCP、IPPTOTO_UDP、IPPROTO_SCTP、IPPROTO_TIPC等,它们分别对应TCP传输协议、UDP传输协议、STCP传输协议、TIPC传输协议。
注意:上面的type和protocol不是可以随意组合的,如SOCK_STREAM不可以跟IPPROTO_UDP组合。当protocol为0时,会自动选择type类型对应的默认协议。
4.返回值:成功返回非负,失败返回-1。
5.errno
函数socket()并不总是执行成功,有可能会出现错误,错误的产生有多种原因,可以通过errno获得:
2.bind()函数
1)作用:将特定的ip地址,port端口号绑定到socket上;bind()函数把一个地址族中的特定地址赋给socket。如对应AF_INET、AF_INET6就是把一个ipv4或ipv6地址和端口号组合赋给socket。将socket与你本机上的一个端口相关联(往往当你在设计服务器端程序时需要调用该函数。随后你就可以在该端口监听服务请求;而客户端一般无须调用该函数)。
2)原型:
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
3)参数:
1.sockfd:即socket描述字:
它是通过socket()函数创建了,唯一标识一个socket。
addr:一个const struct sockaddr *指针,指向要绑定给sockfd的协议地址,包含有关你的地址的信息:名称、端口和IP 地址。这个地址结构根据地址创建socket时的地址协议族的不同而不同。
如ipv4对应的是:
struct sockaddr_in {
sa_family_t sin_family;
in_port_t sin_port;
struct in_addr sin_addr; /* internet address */
//通常设定设定sin_addr为INADDR_ANY(表示任意的意思)
};
/* Internet address. */
/*sin_addr结构体中只有一个唯一的字段s_addr,表示IP地址,该字段是一个整数,一般用函数inet_addr()把字符串形式的IP地址转换成unsigned long型的整数值后再置给s_addr。*/
struct in_addr {
uint32_t s_addr;
};
可以用下面的赋值实现自动获得本机IP地址和随机获取一个没有被占用的端口号:
my_addr.sin_port = 0; /* 系统随机选择一个未被使用端口号 */
my_addr.sin_addr.s_addr = INADDR_ANY; /* 填入本IP地址 */
注意:
1.服务程序在为其s