Linux网络通信

网络模型

七层模型

在这里插入图片描述

四层模型

在这里插入图片描述

TCP : 面向连接,可靠的,面向字节流,支持点对点通信。
UDP : 无连接,不可靠,面向数据报文,支持一对一,一对多,多对多。

通信原理

在这里插入图片描述

常用函数

#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

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

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;}
}