Linux下的socket网络编程

一、网络通信的基本概念

1、TCP和UDP的区别
TCP:传输控制协议,面向连接的服务,安全、可靠(三次握手、响应+重传、四次挥手),速度相对较慢,一般应用在对安全性、完整性有严格要求的场景:FTP、SMTP、HTTP。
UDP:用户数据报文协议,面向无连接的服务,不保证安全、可靠,但大多数情况下是可靠的,相对较快,一般应用在流媒体(在线的视频、音频)。
三次握手与四次挥手的过程:

三次握手:
第一次握手:客户端给服务端发送网络包
	服务端得出结论:客户端能正常到服务端	
第二次握手:服务端给客户端发包
	客户端得出结论:客户端能正常到服务端,服务端能正常到客户端
第三次握手:客户端给服务端发包
	服务端得出结论:服务端能正常到客户端,
四手挥手:
 第一次挥手: 客户端发送关闭请求  ->  服务端
 第二次挥手: 客户端  <-  服务端发送请求响应
    服务端检查是否有末发送完成的数据
 第三次挥手: 客户端  <-  服务端发送确认关闭
 第四次挥手: 客户端发送关闭消息  ->  服务端   

2、消息流
应用层->表示层->会话层->网络层->传输层->数据链路层->物理层->物理层->数据链路层->传输层->网络层->会话层->表示层->应用层。
3、消息包
当socket收到一个要送的数据时,发先数据进行拆分成Bit流,然后再组成(防丢失)数据包(可能会丢包)。

二、套接字

socket是一种接口机制,可以让程序无论使用什么端口、协议,都可以从socket进出数据,它负责了进程与协议之间的连接。
1、编程模型
点对点(p2p):一对一通信。
客户端/服务器(C/S):一对多通信。
2、创建socket
#include <sys/types.h>
#include <sys/socket.h>

int socket(int domain, int type, int protocol);
  功能:创建socket描述符,可以把socket当作文件来看待,发送数据就是写文件,接收数据就是读文件。
  domain:地址类型
   	AF_UNIX/AF_LOCAL/AF_FILE 本地通信(进程间通信)。
   	AF_INET 基本32位IP地址通信,IPv4
   	AF_INET6 基本128位IP地址通信,IPv6
  type:通信协议
   	SOCK_STREAM 数据流协议,TCP
   	SOCK_DGRAM 数据报协议,UDP
  protocol:特别通信协议,给0即可。
  返回值:socket描述符,类似文件描述符。
3、通信地址
struct sockaddr 
{
      sa_family_t sa_family;
      char        sa_data[14];
}
           
struct sockaddr_un
{
  	 __SOCKADDR_COMMON (sun_); //地址类型 参看domain
   	 char sun_path[108]; // socket文件的路径
}; 
  
struct sockaddr_in
{
  	 __SOCKADDR_COMMON (sin_);
   	in_port_t sin_port; // 端口号 大端字节序 
   	struct in_addr sin_addr; // ip地址 大端4字节整数
}
  
struct in_addr
{
   	in_addr_t s_addr;
};

注意:函数接口定义的是sockaddr,而实际提供的是sockaddr_un或sockaddr_in

4、绑定
socket描述符与物理通信载体(网卡或socket文件)绑定在一起。

int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
sockfd:socket描述符:socket函数的返回值
addr:通信地址结构体,实际给的是sockaddr_un或sockaddr_in,需要强制类型转换。
addrlen:通信地址结构体类型的字节数,使用sizeof计算。

5、连接

int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
  sockfd:socket描述符
  addr:通信目标地址
  addrlen:通信地址结构体类型的字节数,使用sizeof计算。
  返回值:在不同的编程模型下返回值意义不同,在本地通信,成功返回加0,失败返回-1。

6、数据接收与发送:recv/send
ize_t recv(int sockfd, void *buf, size_t len, int flags);
ize_t send(int sockfd, const void *buf, size_t len, int flags);
recv/send与read/write功能一样,flags多了是否阻塞的功能(0阻塞,1不阻塞)。
7、关闭套接字:close
如果是网络通信,端口号并不会立即回收,大概会占用3分钟左右。
8、字节序转换
uint32_t htonl(uint32_t hostlong);
功能:把32位本机字节序转换成32位的网络字节序

uint16_t htons(uint16_t hostshort);
功能:把16位本机字节序转换成16位的网络字节序

uint32_t ntohl(uint32_t netlong);
功能:把32位的网络字节序转换成32位的本机字节序

uint16_t ntohs(uint16_t netshort);
功能:把16位的网络字节序转换成16位的本机字节序
9、ip地址转换

inet_aton(const char *cp, struct in_addr *inp)
功能:把点分十进制的ip地址(字符串)转换成32位无符号整数,使用结构指针获取。

in_addr_t inet_addr(const char *cp);
功能:把点分十进制的ip地址(字符串)转换成32位无符号整数,使用返回值直接返回。

char *inet_ntoa(struct in_addr in);
功能:32位无符号整数表示的ip地址,转换成点分十进制的ip地址(字符串)

10、本地通信编程模型
 进程A     			进程B
 创建套接字(AF_LOCAL)  		创建套接字(AF_LOCAL) 
 准备地址(sockaddr_un)  		准备地址(sockaddr_un) 
 绑定(自己的socket/地址)   	连接(connect,连接进程A的地址)。
 接收数据     			发送数据
 关闭套接字     			关闭套接字

三、基于TCP协议的C/S模型

int listen(int sockfd, int backlog);
 功能:设置等待连接的最大数量
 sockfd:被监听的socket描述符
 backlog:等待连接的最大数量(排队的数量)
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
 功能:等待连接sockfd连接
 addr:获取连接的地址
 addrlen:设置连接地址结构体的长度
 返回值:专门用于通信的描述符
编程模型:
 Server       			Client
 创建socket套接字     		创建socket套接字
 准备地址(sockaddr_in,本机地址)  准备地址(服务器地址)
 绑定(bind)      		......
 监听(listen)      		......
 等待连接(accept、fork)   	连接(connect)
 接收请求(read/recv)    		发送请求(write/send)
 响应请求(write/send)    	接收响应(read/recv)
 关闭(close)      		关闭(close)

四、基于UDP协议的C/S模型

UDP协议有着自己专门的接收和发送函数。

ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,const struct sockaddr *dest_addr, socklen_t addrlen);
 功能:UDP协议专用的数据发送函数
 sockfd:套接字描述符
 buf:待发送的缓冲区首地址
 len:待发送的数据字节数
 flags:0阻塞 1不阻塞
 dest_addr:目标计算机的地址
 addrlen:通信地址结构体类型的字节数
 返回值:成功发送的字节数
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,struct sockaddr *src_addr, socklen_t *addrlen);
 功能:UDP协议专用的数据接收函数
 sockfd:套接字描述符
 buf:数据存储位置
 len:最大接收字节数
 flags:0阻塞 1不阻塞
 src_addr: 获取发送者的地址
 addrlen:设置地址结构体的字节数
 返回值:成功接收的字节数
编程模型:
 server        				Client
 创建socket套接字(socket)   		创建套接字(socket)
 准备地址(本机地址sockaddr_in)   	准备地址(目标机地址)
 绑定(bind(sockfd+addr))   		发送请求(sendto)
 接收请求(recvfrom)    			接收响应(recvfrom)
 响应请求(sendto)     			关闭套接字(close)
 关闭套接字(close)
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值