Linux网络编程(套接字编程)
socket套接字编程
udp协议与tcp协议区别
udp协议:
udp协议:用户数据报协议
特性:无连接,不可靠,面向数据报
应用场景:实时性要求大于安全性(类似于短信发送)eg.视频传输
tcp协议:
tcp协议:传输控制协议
特性:面向连接,可靠传输,面向字节流
应用场景:安全性要求大于实时性(类似于打电话)eg.文件传输
客户端和服务端区别
- 客户端:主动发起请求的一端,也就意味着客户端必须提前知道服务端的地址信息(ip+port)因此厂商服务端地址信息一般固定而且被固定写入客户端程序
- 服务端:被动接收请求,提供服务的通信端
udp通信流程
TCP通信流程
TCP通信接口
#include <sys/socket.h>
int socket(int domain ,int type ,int protocal)
- domain: 地址域类型 一般使用AF_INET(表示ipv4地址结构,采用ipv4通信)
- type:套接字类型 (1)SOCK_STREAM: 流式套接字 (可连接,可靠, 供TCP使用) (2) SOCK_DGRAM:数据报套接字(不连接,不可靠,供UDP使用)
- protocal:协议 IPPROTO_TCP -6 IPPROTO_UDP -17(或0 默认协议,根据套接字类型自动配置协议)
- 返回值:返回一个文件描述符(操作句柄) 失败-1
(2)为套接字绑定地址信息
int bind(int sockfd,struct sockaddr* addr, socklen_t addrlen)
- sockfd:创建套接字返回的操作句柄
- addr:当前绑定的地址信息 通过获取到地址域进行区分
- addrlen:地址信息长度
- 返回值;成功0 失败-1
(3)开始监听
int listen(int sockfd,int backlog)
- sockfd:创建套接字返回的操作句柄
- backlog:服务端能够在同一时间处理的最大连接数,将连接的socket放在已完成连接队列中 已完成连接队列的节点数量=backlog+1
(4)客户端发送连接请求
int connect(int sockfd ,struct sockaddr * srvaddr ,socklen_t len)
- sockfd:创建套接字返回的操作句柄
- 服务端地址信息
- 服务端地址长度
- 返回值:失败-1,成功0
(5)服务端获取新建连接
int accept(int sockfd ,struct sockaddr *ciladdr,socklen_t *addrlen)
- sockfd:监听套接字(服务端最早创建的套接字)只用于获取新建连接
- ciladdr:新的连接的服务端地址信息
- addrlen:输入输出参数,指定地址信息长度,以及返回实际长度
- 返回值:新建连接套接字的操作句柄,后续与客户端服务通过此操作句柄完成
(6)发送数据(TCP通信因为新建socket结构中已经包含完整五元组,不需要指定地址)
ssize_t send(int sockfd, void* data, int len, int flag)
- sockfd:创建套接字返回的操作句柄
- data:发送数据空间首地址
- len:发送数据长度
- flag:标志位 默认0 - 阻塞发送(没有发送数据则一直等待发送数据到来)
- 返回值:成功返回实际发送的数据长度 失败-1,连接断开,继续send会触发异常
(7)接收数据
ssize_t recv(int sockfd, void* buf, int len, int flag)
- sockfd:创建套接字返回的操作句柄
- buf:空间地址,用于存放数据
- len:接受数据长度
- flag:标志位 默认0 - 阻塞接收(没有接收到数据则一直等待接收)
- 返回值:返回实际接收到的数据长度 失败-1,连接断开返回0,此时无法通信
(8)关闭套接字
int close(int sockfd)
代码测试:
(1)封装tcpsocket类,实例化类对象通过接口传参调用更加方便
(2)服务端
(3)客户端
上述结果发现问题:服务端流程发生阻塞,只有新创建客户端才会重新唤醒一次服务端,当前服务端不知道什么时候有新的连接到来,什么时候有数据到来,固定流程调用接口会造成阻塞
原因分析:
accept接口,recv接口以及send接口都是阻塞接口,任意一个接口调用都有可能导致服务端阻塞
解决方案:
多执行流并发处理:为每一个客户端都创建一个执行流负责与客户端通信
优点:
- 主线程卡在获取新建连接这,但不会影响客户端的通信
- 某个客户端通信阻塞,也不会影响主线程以及其他线程
- 多线程:普通线程与主线程数据共享,指定入口函数执行
注意:主线程不能随意释放套接字,因为资源共享,一旦释放其他线程将无法再使用套接字
- 多进程:子进程复制父进程,但数据各自独有
注意:
- 僵尸进程的处理,signal子进程发送信号给父进程 进行忽略处理
- 父子进程各自数据独有,父进程不会使用新建套接字,因此子进程创建之后父进程将其释放掉,否则会造成资源泄漏
UDP通信接口
(1)创建套接字
#include <sys/socket.h>
int socket(int domain ,int type ,int protocal)
- domain: 地址域类型 一般使用AF_INET(表示ipv4地址结构,采用ipv4通信)
- type:套接字类型 (1)SOCK_STREAM: 流式套接字 (可连接,可靠, 供TCP使用) (2) SOCK_DGRAM:数据报套接字(不连接,不可靠,供UDP使用)
- protocal:协议 IPPROTO_TCP -6 IPPROTO_UDP -17(或0 默认协议,根据套接字类型自动配置协议)
- 返回值:返回一个文件描述符(操作句柄) 失败-1
(2)为套接字绑定地址信息
int bind(int sockfd,struct sockaddr* addr, socklen_t addrlen)
- sockfd:创建套接字返回的操作句柄
- addr:当前绑定的地址信息 通过获取到地址域进行区分
- addrlen:地址信息长度
- 返回值;成功0 失败-1
(3)接受数据
ssize_t recvfrom(int sockfd, void* buf, int len, int flag, struct sockaddr* srcaddr, socklen_t addrlen)
- sockfd:创建套接字返回的操作句柄
- buf:空间地址,用于存放数据
- len:接受数据长度
- flag:标志位 默认0 - 阻塞接收(没有接收到数据则一直等待接收)
- srcaddr:本条数据源端地址信息
- addrlen:输入输出参数 -指定要接收多长的地址结构,并且返回实际接收到的地址长度
- 返回值:返回实际接收到的数据长度 失败-1
(4)发送数据
ssize_t sendto(int sockfd, void* data, int len, int flag, struct sockaddr* peeraddr, socklen_t addrlen)
- sockfd:创建套接字返回的操作句柄
- data:发送数据空间首地址
- len:发送数据长度
- flag:标志位 默认0 - 阻塞发送(没有发送数据则一直等待发送数据到来)
- peeraddr:对端地址信息
- addrlen:输入输出参数 -指定要发送多长的地址结构,并且返回实际发送的地址长度
- 返回值:返回实际发送的数据长度 失败-1
(5)关闭套接字
int close(int sockfd)
(6)字节序转换接口
#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位数据网络到主机字节序转换
注:port端口转换使用s ip地址转换用l
(7)IP地址转换接口
in_addr_t inet_addr(const char* cp) 将字符串点分十进制ip地址转换为整型网络字节序ip地址 192.168.2.2 -> 0xc0a80202
char *inet_ntoa(struct in_addr in) 将整型网络字节序ip地址转换为字符串点分十进制ip地址 in.s_addr=0xc0a80202 -> 192.168.2.2
代码测试:
(1)封装udpsocket类,实例化类对象通过接口传参调用更加方便
(2)服务端
(3)客户端
查看网络状态信息:
netstat
- -a或--all 显示所有连线中的Socket。查看所有
# netstat -a
- -A<网络类型>或--<网络类型> 列出该网络类型连线中的相关地址。
- -c或--continuous 持续列出网络状态。
- -C或--cache 显示路由器配置的快取信息。
- -e或--extend 显示网络其他相关信息。
- -F或--fib 显示路由缓存。
- -g或--groups 显示多重广播功能群组组员名单。
- -h或--help 在线帮助。
- -i或--interfaces 显示网络界面信息表单。
- -l或--listening 显示监控中的服务器的Socket。
- -M或--masquerade 显示伪装的网络连线。
- -n或--numeric 直接使用IP地址,而不通过域名服务器,不以服务名称显示
# netstat -an
- -N或--netlink或--symbolic 显示网络硬件外围设备的符号连接名称。
- -o或--timers 显示计时器。
- -p或--programs 显示正在使用Socket的程序识别码和程序名称。查看当前网络状态对应的进程
# netstat -ap
- -r或--route 显示Routing Table。
- -s或--statistics 显示网络工作信息统计表。
- -t或--tcp 显示TCP传输协议的连线状况。
# netstat -at
- -u或--udp 显示UDP传输协议的连线状况。
# netstat -au
- -v或--verbose 显示指令执行过程。
- -V或--version 显示版本信息。
- -w或--raw 显示RAW传输协议的连线状况。
- -x或--unix 此参数的效果和指定"-A unix"参数相同。
- --ip或--inet 此参数的效果和指定"-A inet"参数相同。
Linux网络编程(套接字编程)相关推荐
- UNIX网络编程---套接字编程简介(三)
UNIX网络编程---套接字编程简介 一.概述 从这里开始正式开始网络编程之旅,所有的函数都是基本的库函数.这些都是网络编程的基础.Come on!!!! 二.套接字地址结构 大多数套接字函数都需要一 ...
- Linux之socket套接字编程20160704
介绍套接字之前,我们先看一下传输层的协议TCP与UDP: TCP协议与UDP协议的区别 首先咱们弄清楚,TCP协议和UCP协议与TCP/IP协议的联系,很多人犯糊涂了,一直都是说TCP/IP协议与UD ...
- linux sock_raw原始套接字编程
sock_raw原始套接字编程可以接收到本机网卡上的数据帧或者数据包,对与监听网络的流量和分析是很有作用的.一共可以有3种方式创建这种socket 1.socket(AF_INET, SOCK_R ...
- 【网络】网络基础套接字编程详解
目录 网络初识 1.网络协议初识 2.网络协议的分层: OSI分层模型--->网络理论模型: TCP/IOP五层模型--->工业中采用的网络模型 为什么要有网络分层? 3.网络数据的封 ...
- Linux IPv6 UDP套接字编程示例
udp ipv6套接字编程和ipv4接口类似,参数略有不同,流程都包括创建套接字.绑定地址.发送等. 下面是一个udp ipv6 demo, 包括创建ipv6套接字.绑定地址和发送数据等. 首先先在l ...
- 网络编程套接字编程-代码实现-复习总结
文章目录 一.客户库例程设计 背景知识 前言知识 addrinfo 结构体 getaddrinfo() freeaddrinfo() socket() connect() close() gai_st ...
- C/C++Unix网络编程-套接字编程简介
套接字地址结构 套接字的地址结构可以在两个方向上传播:从进程到内核和从内核到进程. IPV4套接字地址结构 sin_len是长度字段,有的平台上的套接字没有这个东西,因为有外置的sizeof运算符.不 ...
- python 图形化socket编程_Python黑帽编程2.8 套接字编程
Python黑帽编程2.8 套接字编程 套接字编程在本系列教程中地位并不是很突出,但是我们观察网络应用,绝大多数都是基于Socket来做的,哪怕是绝大多数的木马程序也是如此.官方关于socket编程的 ...
- Python黑帽编程2.8 套接字编程
Python黑帽编程2.8 套接字编程 套接字编程在本系列教程中地位并不是很突出,但是我们观察网络应用,绝大多数都是基于Socket来做的,哪怕是绝大多数的木马程序也是如此.官方关于socket编程的 ...
- TCP和UDP套接字编程
一.Socket简单介绍 如果要在应用层调用传输层的服务,进行相关程序的设计,就要涉及到套接字编程.套接字也称之为Socket,本质上它就是利用传输层提供的一系列Api来进行网络应用程序的设计. 网络 ...
最新文章
- python水仙花数_scratch与pythonc++的不同,你了解吗?
- c#对oracle操作时候 出现的乱码问题。
- springboot使用原生servlet、filter、listener
- Embedded web server initialization - jar file default-mimetypes.properties
- 计算机安全基础:认证技术知识笔记
- 嘘,这是手淘双11 GMV 暴涨的秘密
- 为什么不用 LinkedList
- vs 2005 多語言
- 统计学习方法学习笔记一
- java中queue与stroke,ae中stroke的用法
- Jmeter基础篇(01):如何进行post接口压力测试
- erroe C1083:无法打开包括文件(源文件)
- 达梦数据库 防火墙设置
- Mac版 微信 撤回消息拦截两种方法
- Strong-Convexity
- 苹果为App订阅付费添加二次确认 避免意外支付情况
- 调用CachedRowSetImpl类时出现错误
- STS (Spring Tool Suite) 目录和作用初级
- 分享诗集-中国原创诗歌创作分享中心,欢迎博客园喜欢诗词的加入【诗词在线】...
- wincc按钮控制的vb脚本_VB操作wincc脚本心得