linux 网络编程

socket 高级io sql数据库

TCP协议分成两个不同的协议:
用来检测网络传输中差错的传输控制协议TCP,是可靠的传输
专门负责对不同网络进行互联网协议IP,不可靠的传输
两个最有代表的协议促成了TCP/IP协议

网络采用分层的思想:
1.每一层实现不同的功能,对上层的数据做透明传输
2.每一层向上层提供服务,同时下层提供的服务

OSI开放系统互联网模型:
是一个理想化的模型,尚未有完整的实现
七层结构:
应用层
表示层
会话层

传输层
网络层
数据链路层
物理层

TCP/IP协议族体系结构:是Internet事实上的工业标准
一共有四层:
用户态:
应用层:FTP,HTTP......
内核态:
传输层:TCP、UDP,通过协议规定数据的处理
网络层:IP、ICMP、IGMP,通过协议控制端到端的传输(数据链路)
网络接口和物理层:以太网、令牌环网、FDDI等,使用驱动屏蔽硬件差异(无线与有线,移动流量等)





TCP(流式):传输控制协议,提供面向连接的,一对一的可靠数据传输协议,如:打电话,QQ等
即数据无误、数据无丢失、数据无失序、数据无重复到达的通信

UDP(报式):用户数据报协议,提供不可靠,无连接的尽力传输协议,如:流媒体,文件传输
因为发送前不需要进行连接,所以是一种高效的传输


socket编程:
socket是一个网络编程的接口,它是一种特殊的文件描述符(对它执行IO操作)

跨主机的传输要注意的问题:
1.字节序问题:

大端:低地址处存放高字节
小端:低地址处存放低字节
不同的主机平台对于数据的存储也会是不一样的,解决方式如下:
主机字节序:host
网络字节序:network

主机转网络:htons、htonl
网络转主机:ntohs、ntohl
单字节的数据不需要做转换

2.数据对齐方式:
一般不处理数据对齐方式,编译器优化运行速度会采用字节对齐,一般是x86 4字节(64 位一样4个字节,为了兼容32位机),long 会跟着系统变32位4字节,64位8字节,double 8字节不会,char short 会转化为4字节 
收发双发规定不采用对齐,结构体
不对齐__attribute__((packed))

long a 64位 8字节

long a 32位 4字节

int





3.类型长度问题:
标准C中只规定了数据类型的名称,但并未规定其大小
解决方法:
使用定长数据类型:
如:int32_t,uint32_t,int64_t,uint64_t,int8_t,uint8_t

SOCEKT编程其实就是混合网络层和传输层的各种协议

socket(协议族,传输方式,0):成功返回一个文件描述符,失败返回-1并设置errno
协议族:
AF_INET:ipv4
AF_INET6:ipv6
传输方式:
SOCK_STREAM;流式
SPCK_DGRAM:报式
最后一个参数:写0的意思是使用协议族中默认支持传输方式的协议

TCP是基于连接数据可靠的传输方式,并不是一定不丢包,
只是说如果你能接受到包那么保证包中的内容是正确的

以单字节的方式进行传输的方式称为流式套接字

UDP是无连接的数据不可靠的传输方式,如果成功收到包,不确定包中数据是否正确
以数据分组的方式进行传输的方式称为报式套字,如结构体传输

IP、端口、协议:
ip+协议:确定唯一的一台主机
ip+端口+协议:确定一台主机上的唯一的进程
端口:周知端口:1-1024
用户端口:1024-65535

协议:通信双方所规定的对话格式



报式套接字:
被动端-》服务器端:先收包的一方(先运行)
1.取得socket
socket()

2.给socket绑定本地地址
bind(套接字文件描述符,地址结构体指针,地址长度):成功返回0,失败返回-1并设置errno
地址结构体的格式:如果是AF_INET就man 7 ip查看address format一栏

如果是AF_INET6就man 7 ipv6查看address format一栏

将点分式ip地址转整数:
inet_pton(协议族,点分式ip地址,转换完成后填写的地址)

将整数ip地址转点分式:
inet_ntop(协议族,ip地址大整数的地址,转换完成后填写的地址,回填地址的大小)

3.收/发消息
recvfrom(套接字文件描述符,存放的空间,空间的大小,0,发送端的ip地址回填处,回填ip的地址长度):成功返回接收到的字节大小,失败返回-1并设置errno
回填ip的地址长度:在第一次调用收消息时需要初始化,初始化为ip地址结构体的大小
4.关闭socket
close(套接字描述符):关闭网络套接字

netstat -anu:查看udp套接字状态
netstat -ant:查看流式套接字状态

主动端-》客户端:先发消息
1.取得socket
2.给socket绑定地址(可省略)
3.收/发消息
sendto(套接字描述符,发送的消息的地址,发送消息的大小,0,发送到指定服务器的ip地址,ip地址的长度):发送消息至指定的服务器,成功返回成功发送的字节,失败返回-1并设置errno

4.关闭socket



广播地址:255.255.255.255,默认是不能够发送广播,所以需要设置setsockopt,man 7 socket-》sockeopt
setsockopt(套接字描述符,SOL_SOCKET,SO_BROADCAST,是否打开,参数大小):设置网络套接字打开使用广播功能,成功返回0,失败返回-1并设置errno
例如:发送方向广播地址发消息,所以改发送端
int val = 1;
setscokopt(sfd,SOL_SOCKET,SO_BROADCAST,&val,sizeof(var));




组播/多播:需要约定一个多播组地址如:224.2.2.2,设置看man 7 ip socket-》socketopt
创建多播组:发送(客户)端创建
struct ip_mreqn mreq;
inet_pton(AF_INET,"224.2.2.2",&mreq.imr_multiaddr); //设置多播组地址
inet_pton(AF_INET,"0.0.0.0",&mreq.imr_address); //绑定本地地址
mreq.imr_ifindex = if_nametoindex("etho"); //设备索引号,可以通过命令 ip ad sh查看,通过函数if_nametoindex("设备名称")可获取到设备的索引号
setsockopt(sfd,IPPROTO_IP,IP_MULTICAST_IF,&mreq,sizeof(mreq)):创建多播组

加入多播组:接收端加入
struct ip_mreqn mreq;
inet_pton(AF_INET,"224.2.2.2",&mreq.imr_multiaddr); //设置多播组地址
inet_pton(AF_INET,"0.0.0.0",&mreq.imr_address); //绑定本地地址
mreq.imr_ifindex = if_nametoindex("etho"); //设备索引号
setsockopt(sfd,IPPROTO_IP,IP_ADD_MEMBERSHIP,&mreq,sizeof(mreq));

所有多播组成员都会默认加入一个多播地址224.0.0.1,所以往该地址发消息,等同于广播发送

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值