day_15_socket模型、TCP模型

一、基于socket的一对一通信模型

1.1 相关函数的解析

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

功能:
  主要用于创建用于交流 / 通信的端点;

参数:
  第一个参数:协议族/域,决定了本地通信还是网络通信;
    AF_UNIX / AF_LOCAL - - - - - 表示实现本地通信
    AF_INET - - - - - - - - - - - - - - - -表示实现基于IPv4的网络通信
  第二个参数:具体的通信类型,决定了具体的通信协议;
    SOCK_STREAM - - - - 提供有序的、可靠的、双向的、面向连接的字节流通信方式,也就是基于TCP协议的通信方式
    SOCK_DGRAM - - - - - 提供不可靠的,非面向连接的数据报通信方式,也就是基于UDP协议的通信方式
  第三个参数:具体的特殊协议,默认给0即可;

返回值:
  success —- 文件描述符,error —- -1;

(2)通信地址的常用地址数据类型

  a. struct sockaddr类型 - - - - 主要用于函数的形参类型,基本不会定义结构体变量去使用;

struct sockaddr
{
    sa_family_t  sa_family;
    char        sa_data[14];
}

  b. struct sockaddr_un类型 - - - - 主要用于实现本地通信;

#include <sys/un.h>
struct sockaddr_un
{
    sa_family_t    sun_family;  //协议族,和socket()的第一个实参保持一致即可;
    char           sun_path[];  //socket文件的路径名;
}

  c. struct sockaddr_in类型 - - - - 主要用于网络通信;

#include <netinet/in.h>
struct sockaddr_in
{
    sa_family_t         sin_family;  //协议族 AF_INET
    in_port_t           sin_port;    //端口号
    struct in_addr       sin_addr;    //IP地址
}
struct in_addr
{
    in_addr_t    s_addr;  //整数类型的IP地址
}
(3)bind()
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

功能:
  主要用于绑定socket和指定的通信地址;

参数:
  第一个参数:socket的描述符,socket()的返回值;
  第二个参数:结构体指针,用于指定通信地址,需要进行类型转换;
  第三个参数:通信地址的大小,使用sizeof()计算即可;

(4)connect()
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

功能:
  主要用于建立socket到通信地址的连接,参数和返回值参考bind()即可;

(5)字节序转换函数
#include <arpa/inet.h>
uint32_t htonl(uint32_t hostlong);
/* 主要用于将32位二进制组成的主机字节序转换为网络字节序 */
uint16_t htons(uint16_t hostshort); 
/* 主要用于将16位二进制组成的主机字节序转换为网络字节序 */
uint32_t ntohl(uint32_t netlong);
/* 主要用于将32位二进制组成的网络字节序转换为主机字节序 */
uint16_t ntohs(uint16_t netshort);
/* 主要用于将16位二进制组成的网络字节序转换为主机字节序 */
(6)IP地址的转换函数
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
in_addr_t inet_addr(const char *cp);

功能:
  主要用于将字符串形式的IP地址转换为整数类型的IP地址;

char *inet_ntoa(struct in_addr in);

功能:
  主要用于将结构体类型的IP地址转换为字符串类型;

二、基于TCP协议的网络通信模型

2.1 通信模型

服务器:
 (1)创建socket,使用socket();
 (2)准备通信地址,使用结构体类型;
 (3)绑定socket和通信地址,使用bind();
 (4)监听,使用listen();
 (5)响应客户端的连接请求,使用accept();
 (6)进行通信,使用send()/recv();
 (7)关闭socket,使用close();

客户端:
 (1)创建socket,使用socket();
 (2)准备通信地址,使用服务器的地址;
 (3)连接socket和通信地址,使用connect();
 (4)进行通信,使用send()/recv();
 (5)关闭socket,使用close();

2.2 相关函数的解析

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

功能:
  主要用于将参数sockfd所指定的socket标记为被动的socket,也就是原来的socket是可以用于通信的,但是标记为被动的socket之后,专门用于响应即将到来的连接请求,不再用于通信;

参数:
  第一个参数:socket描述符,socket()的返回值;
  第二个参数:主要用于指定悬而未决连接请求队列的最大长度,当该队列为满时,有客户端发来连接请求,则会被拒绝;

(2)accept()
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

功能:
  主要用于响应指定socket上面的一个连接请求;该函数会提取悬而未决连接请求队列中的第一个连接请求进行响应,响应的方式就是再创建一个连接好的socket进行通信;

参数:
  第一个参数:socket的描述符,socket()的返回值;
  第二个参数:结构体指针,用于带出客户端的通信地址;
  第三个参数:指针类型,用于带出客户端通信地址的大小;

返回值:
  success —- 通信socket的描述符,error —- -1;

(3)send()
#include <sys/types.h>
#include <sys/socket.h>
ssize_t send(int sockfd, const void *buf, size_t len, int flags);

功能:
  主要用于向指定的socket发送指定的数据内容;

参数:
  第一个参数:socket描述符,用于通信的socket;
  第二个参数:被发送数据的首地址;
  第三个参数:被发送数据的大小;
  第四个参数:发送的标志,默认给0即可;

返回值:
  success —- 实际发送数据大小,error —- -1;

(4)recv()
#include <sys/types.h>
#include <sys/socket.h>
ssize_t recv(int sockfd, void *buf, size_t len, int flags);

功能:
  主要用于接收参数指定socket中的数据;

参数:
  第一个参数:socket描述符,用于通信的socket;
  第二个参数:存放接收到数据的缓冲区首地址;
  第三个参数:期望接收的数据大小;
  第四个参数:接收的标志,默认给0即可;

返回值:
  success —- 实际接收数据大小,error —- -1;

练习:
  使用基于tcp协议的通信模型实现一对多通信
   a. 要求服务器可以不断地响应客户端的连接请求;
    => 使用while(1)无限循环
   b. 要求服务器可以同时接收多个客户端发来的消息;
    => 使用fork()创建子进程
   c. 要求服务器可以和每一个客户端不断进行通信;
    => 使用while(1)无限循环
   d. 要求当客户端发来”bye”时,表示客户端下线;
    => 使用strcmp()比较
   e. 要求客户端发送的消息由键盘输入;
    => 使用scanf()/gets()/fgets()
   f. 要求关闭服务器请按ctrl+c来实现;
    => 对信号SIGINT进行自定义处理

明日预报:
 (1)网络编程;
 (2)多线程;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值