博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Socket编程
阅读量:4136 次
发布时间:2019-05-25

本文共 2452 字,大约阅读时间需要 8 分钟。

什么是Socket

Socket:看成用户进程与内核网络协议栈的编程接口。

Socket不仅可以用于本机的进程间通信,还可以用于网络上不同主机的进程间通信。

(不同主机可能经过路由器,路由器工作在IP层(网络层))

不同进程间通信,是一种全双工的模式,可以在不同体系架构的进程间通信(比如手机上的CPU是ARM,PC机上的是X86系统架构),软件平台可以不一样,硬件平台也可以不一样。

IPV4套接口地址结构

地址属性:

这里写图片描述
上述地址是:
sockaddr_in

sin_family:IPV4是AF_INET。由于socket不仅仅支持TCP/IP,还支持Unix域协议编程,不同协议,地址结构形式可能不一样。

sin_port是16位,2个字节,和sin_addr是4个字节。

所以有通用地址结构 :

sockaddr

这里写图片描述

网路字节序

大端:Big Endian 最高有效位存储在最低内存地址处,最低有效位存在在最高内存地址处。

小端:little Endian 最高有效位存储在最高内存地址处。

网络字节序:是大端字节序。

主机A和主机B通信,两个主机如果不是同一种形式的字节序,就需要转换。不同主机之间,可能有不同的字节序,如

x86为小端字节序,Motorola 6800为大端字节序,ARM字节序是可配置的。

#include
#include
#pragma comment(lib, "ws2_32") //http://bbs.csdn.net/topics/190038207//#include
//包含winsock这个头文件,内容是网络编程socket相关部分API//#pragma comment(lib,"Ws2_32.lib") //这是链接API相关连的Ws2_32.lib静态库using namespace std;int main(){ unsigned int A = 0x12345678;//0x开头,是以16进制表示,0开头是8进制,没有的是10进制 //注意对A的理解,因为FF是1111 1111,一个字节。所以0x12345678是可以用四个字节的int表示的,没问题。 //unsigned int可以表示最大的数是:4294967295,40多个亿。 cout << sizeof(A) << endl;//sizeof表示一个int占用字节数,和A的实际值无关。 unsigned char *p = (unsigned char *)&A;//取A的地址,在内存中占用4个字节(其实内存中每个字节占用的位置都有一个边号,这就是地址) //这里需要注意的是,A的地址的值是存放到p指针指向的那块地址处,那块地址存的内容是A的地址,但那块地址的值和A没关系 int addr_p = (int)p; cout <
<
<< endl; //这个输出的是p的地址,然后对p的地址进行int强制转换,并以十六进制输出 cout << hex << *(int *)addr_p << endl; //画个图就明白了 for (int i = 0; i < 4;i++) cout <
<<(int)p[i]; //78 56 43 12 最高有效位12存在p[4],即内存的高有效位,属于小端存储 cout << endl; //printf("%0x_%0x_%0x_%0x", p[0], p[1], p[2], p[3]); unsigned long y = htonl(A);//转换成网络字节序 p = (unsigned char *)&y; for (int i = 0; i < 4; i++) cout << hex << (int)p[i]; cout << endl; //测试地址转换函数 对192.168.0.100,它对应的32位整数是什么样的? //in_addr_t inet_addr(const char *cp),将点分十进制转化为32位整数 unsigned long addr = inet_addr("192.168.0.100"); unsigned long addr_oct = ntohl(addr); cout <
<< addr_oct << endl; //这里不指明oct,默认会以hex输出,因为在上面的cout中已经指出了hex格式输出了 struct in_addr ipaddr; //char *addr_p = inet_ntoa(struct in_addr in); 将 /*memcpy(&ipaddr, &addr_oct, 4);*/ ipaddr.S_un.S_addr = 30052000144;//30052000144是网络字节序转换的结果,是大端模式,所以肯定不是原来的IP地址对应的32位整数了。 cout << inet_ntoa(ipaddr) << endl; ipaddr.S_un.S_addr = inet_addr("192.168.0.100"); char *sss = inet_ntoa(ipaddr); cout << sss << endl; return 0;}

这里写图片描述

套接字类型

流式套接字:SOCK_STREAM

提供无面向连接的,可靠的数据传输服务,数据无差错,无重复的发送,且按发送顺序接收。

数据报式套接字:SOCK_DGRAM

提供无连接服务。不提供无错保证,数据可能丢失或重复,并且接收顺序混乱。

原始套接字:SOCK_RAW

直接将应用层封装成IP层认识的数据格式。

你可能感兴趣的文章
servlet中的cookie和session
查看>>
过滤器及JSP九大隐式对象
查看>>
软件(项目)的分层
查看>>
菜单树
查看>>
Servlet的生命周期
查看>>
JAVA八大经典书籍,你看过几本?
查看>>
《读书笔记》—–书单推荐
查看>>
JAVA数据类型
查看>>
【Python】学习笔记——-6.2、使用第三方模块
查看>>
【Python】学习笔记——-7.0、面向对象编程
查看>>
【Python】学习笔记——-7.2、访问限制
查看>>
【Python】学习笔记——-7.3、继承和多态
查看>>
【Python】学习笔记——-7.5、实例属性和类属性
查看>>
git中文安装教程
查看>>
虚拟机 CentOS7/RedHat7/OracleLinux7 配置静态IP地址 Ping 物理机和互联网
查看>>
Jackson Tree Model Example
查看>>
常用js收集
查看>>
如何防止sql注入
查看>>
springmvc传值
查看>>
在Eclipse中查看Android源码
查看>>