网络模型
七层模型
四层模型
TCP : 面向连接,可靠的,面向字节流,支持点对点通信。
UDP : 无连接,不可靠,面向数据报文,支持一对一,一对多,多对多。
通信原理
常用函数
c
复制代码
#include <sys/socket.h>
//创建套接字
int socket (int domain, int type, int protocol);
/*
domain : 地址族
AF_UNIX/AF_LOCAL/AF_FILE: 本地通信(进程间通信);
AF_INET: 基于TCP/IPv4(32位IP地址)的网络通信;
AF_INET6: 基于TCP/IPv6(128位IP地址)的网络通信;
AF_PACKET: 基于底层包接口的网络通信。
type : 通信协议,取值:
SOCK_STREAM: 数据流协议,即TCP协议;
SOCK_DGRAM: 数据报协议,即UDP协议。
protocol : 一般不使用,置为0.
*/
//准备通信地址
//A. 基本地址类型
struct sockaddr
{
sa_family_t sa_family; // 地址族
char sa_data[14]; // 地址值
};
//B. 本地地址类型
#include <sys/un.h>
struct sockaddr_un
{
sa_family_t sun_family; // 地址族
char sun_path[]; // 套接字文件路径
};
//C. 网络地址类型
#include <netinet/in.h>
struct sockaddr_in
{
// 地址族
sa_family_t sin_family;
in_port_t sin_port;
// IP地址
struct in_addr sin_addr;
};
//绑定套接字
int bind (int sockfd, const struct sockaddr* addr,socklen_t addrlen);
/*
sockfd : 套接字
addr : 通信地址
addrlen : 通信地址字节长度
*/
//监听
int listen (int sockfd, int backlog);
/*
sockfd : 套接字
backlog : 最大连接请求
*/
//接收请求
int accept (int sockfd, struct sockaddr* addr,socklen_t* addrlen);
//成功返回套接字
//建立连接
int connect (int sockfd, const struct sockaddr* addr,socklen_t addrlen);
例子
server
c
复制代码
int server_run(){
pthread_mutex_init(&lock,NULL);//初始化互斥锁
list = slink_create(); //创建链表
file_read(list); //读取文件
//创建套接字
sockfd = socket(AF_INET,SOCK_STREAM,0);
if(sockfd == -1){
perror("socket");
return -1;
}
//准备通信地址
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(PORT);
addr.sin_addr.s_addr = inet_addr(IP);
socklen_t len = sizeof(addr);
//捆绑通信地址和套接字
int ret = bind(sockfd,(const struct sockaddr *)&addr,len);
if(ret == -1){
perror("bind");
return -1;
}
//监听
ret = listen(sockfd,MAX);
if(ret == -1){
perror("listen");
return -1;
}
//接收连接请求
while(1){
signal(SIGINT,myexit);
struct sockaddr_in caddr = {};
socklen_t clen = sizeof(caddr);
int cfd = accept(sockfd,(struct sockaddr *)&caddr,&clen);
//有新的连接时,产生新的文件套接字,作为纽带
if(cfd == -1){
perror("accept");
return -1;
}
pthread_t id;
int ret = pthread_create(&id,NULL,run,(void*)&cfd);
assert(ret == 0);
ret = pthread_detach(id);
assert(ret == 0);
}
}
client
c
复制代码
int client_run(){
//创建套接字
int sockfd = socket(AF_INET,SOCK_STREAM,0);
if(sockfd == -1){
perror("socket");
return -1;
}
//准备通信地址
struct sockaddr_in addr = {};
addr.sin_family = AF_INET;
addr.sin_port = htons(PORT);
addr.sin_addr.s_addr = inet_addr(IP);
socklen_t len = sizeof(addr);
//连接通信
int ret = connect(sockfd,(const struct sockaddr *)&addr,len);
if(ret == -1){
perror("connect");
return -1;
}
}