转自
socket到底是什么 https://blog.csdn.net/YEYUANGEN/article/details/6799575
基于kvm的qemu中宿主机和虚拟机间的通信 https://www.cnblogs.com/noxy/p/6369612.html
一篇搞懂 TCP UDP HTTP socket socket连接池 https://segmentfault.com/a/1190000014044351
qga是一个运行在虚拟机内部的普通应用程序(可执行文件名称默认为qemu-ga,服务名称默认为qemu-guest-agent),其目的是实现一种宿主机和虚拟机进行交互的方式,这种方式不依赖于网络,而是依赖于virtio-serial(默认首选方式)或者isa-serial,而QEMU则提供了串口设备的模拟及数据交换的通道,最终呈现出来的是一个串口设备(虚拟机内部)和一个unix socket文件(宿主机上)。
qga通过读写串口设备与宿主机上的socket通道进行交互,宿主机上可以使用普通的unix socket读写方式对socket文件进行读写,最终实现与qga的交互,交互的协议与qmp(QEMU Monitor Protocol)相同(简单来说就是使用JSON格式进行数据交换),串口设备的速率通常都较低,所以比较适合小数据量的交换。
备注:
什么是套接字socket?
Socket 可以被定义描述为两个应用通信通道的端点。一个 Socket 端点可以用 Socket 地址来描述, Socket 地址结构由 IP 地址,端口和使用协议组成( TCP or UDP )。http协议可以通过socket实现,socket在传输层上实现。从这个角度来说,socket介于应用层和传输层之间。但是socket作为一 种进程通信机制,操作系统分配唯一一个socket号,是依赖于通信协议的,但是这个通信协议不仅仅是 tcp或udp,也可以是其它协议。
在同一台服务器上,用tcp socket与unix domain socket有什么区别?
如图所示,对于进程间通讯的两个程序,unix domain socket的流程不会走到TCP 那层,直接以文件形式,以stream socket通讯。如果是TCP socket,则需要走到IP层。对于非同一台服务器上,TCP socket走的就更多了。
socket到底是什么
1)服务端在8088上监听,然后生成一个新的socket与client通讯。(注意:服务器端监听端口是
不变的,但socket连接可以一直生成,一个线程对应一个socket.)
同一时刻,一个端口只能建立一个连接。
在一个端口监听,但是在监听端口的同时,生成一个等待队列,每一个来自客户端的连接都会送入等待队列中,服务器利用一定的算法进行选择相应的连接请求处理,所以在一个端口可以监听多各请求嘛。如果同时的连接过多,服务器相应每个连接的时间就会相应的变长。就会变慢。
2)QQ的实现方法就是在登陆的时候告诉服务器你已经登陆,发送消息的时候,首先你会发送一个包给服务器,服务器查看你需要发送的对方是否在线,如果在线就返回包告诉你对方在线,然后你就会和对方建立一个连接,然后直接发消息给对方,如果对方不在线,那么就会通过服务器转发你这次的消息
3)网络IO数与你的CPU数目一致将是比较好的选择(考虑到多线程多进程可以提高效率)。
没有必要每个客户分配一个端口。绝对是一种无谓的浪费。
4.有人知道socket监听的一个端口.最多可以有多少个客户连接?
1)listen()中有个参数,应该是确定并行连接客户数?!
2)The maximum length of the queue of pending connections. If this value is SOMAXCONN, then the underlying service provider responsible for socket s will set the backlog to a maximum "reasonable " value. There is no standard provision to find out the actual backlog value.
3)linux2.4下,最多可以有1024个socket连接
4)同时连接请求好像是5个(是连接请求,不是连接),可保持的链接理论上是65535(2字节的SOCKET端口号),
答:C和S是相对而言的,发起连接的一方就是C,而监听端口接受连接的一方就是S,C如果不知道S监听的端口,怎么发起连接呢,
另外,对于S而言,端口是S上各个服务的区分标志,如果用错误的端口号去连接,是不能获得正确的服务的。
client的端口是不需要指定的,Server绑定端口,然后监听,client使用server的IP和端口建立socket连接
又说“通过socket()函数可以创建一个套接字,然后再把它绑定到端口号...”
那么套接字socket的概念究竟到哪里为止呢?是仅限于socket()返回的文件描述符?还是是IP和端口号的组合?如果是,那么socket()调用之后产生的套接字描述符的作用是什么呢? 套接字描述符,IP地址,端口号三者间的关系是怎样的?
谢谢各位前辈解答。
答:一个socket句柄代表两个地址对 “本地ip:port”--“远程ip:port”
如果说socket代表一个两个地址对,那么句柄的作用是不是仅仅是在bind() 或者 connect () 之后的用于区分和标记这样的地址对呢?因为这样他才能和网络的概念联系起来。这样的话,socket的意义应该是说用文件描述符描述的通信双方的IP地址和端口号地址对?(而文件描述符是区分这些地址对的标记?)
答:socket为内核对象,由操作系统内核来维护其缓冲区,引用计数,并且可以在多个进程中使用。
至于称它为“句柄”“文件描述符”都是一样的,它只不过是内核开放给用户进程使用的整数而已
我想我的问题是在于句柄和ip、port的关系,不知道我这样说对否:
1. 每一个socket 本质上都是指一个ip地址和端口对
2. 为了操作这样的地址对,使用了文件描述符
3. socket()函数只创建了一个普通的文件描述符,在进行bind()或者connect()之前并不能说创建了用于网络通讯的套接字
4. 只有在进行了bind()或者connect()之后socket才被创立起来
答:socket()创建了一个socket内核对象。
accept或者connect后,才可以对socket句柄读写。因为只有在 connect或者bind,listen,accept后才会设置好socket内核对象里边的ip和端口
二、socket和端口理解
在windows下叫句柄,在linux下叫文件描述符 。
socket为内核对象,由操作系统内核来维护其缓冲区,引用计数,并且可以在多个进程中使用。 至于称它为“句柄”“文件描述符”都是一样的
我假定读者已经对于socket连接的建立过程和各种状态转换比较熟悉了,因为这篇文档的目的是澄清概念,而不是介绍概念。
在使用socket编程时,我们都知道在网络通信以前首先要建立连接,而连接的建立是通过对socket的一些操作来完成的。那么,建立连接的过程大致可以分为以下几步:
1) 建立socket套接字。
2) 给套接字赋予地址,这个地址不是通常的网络地址的概念。
3) 建立socket连接。
使用socket建立套接字的时候,我们实际上是建立了一个数据结构。这个数据结构最主要
的信息是指定了连接的种类和使用的协议,此外还有一些关于连接队列操作的结构字段
(这里就先不涉及他们了)。
当我们使用socket函数以后,如果成功的话会返回一个int型的描述符,它指向前面那个
被维护在内核里的socket数据结构。我们的任何操作都是通过这个描述符而作用到那个数
据结构上的。这就像是我们在建立一个文件后得到一个文件描述符一样,对文件的操作都
是通过文件描述符来进行的,而不是直接作用到inode数据结构上。我之所以用文件描述
符举例,是因为socket数据结构也是和inode数据结构密切相关,它不是独立存在于内核
中的,而是位于一个VFS inode结构中。所以,有一些比较抽象的特性,我们可以用文件
操作来不恰当的进行类比以加深理解。
如前所述,当建立了这个套接字以后,我们可以获得一个象文件描述符那样的套接字描述
符。就象我们对文件进行操作那样,我们可以通过向套接字里面写数据将数据传送到我们
指定的地方,这个地方可以是远端的主机,也可以是本地的主机。如果你有兴趣的话,还
可以用socket机制来实现IPC,不过效率比较低,试试也就行了(我没有试过)。
依照建立套接字的目的不同,赋予套接字地址的方式有两种:服务器端使用bind,客户端
使用connetc。
Bind:
我们都知道,只要使用IP, prot就可以区分一个tcp/ip连接(当然这个连接指的是一个
连接通道,如果要区分特定的主机间的连接,还需要第三个属性 hostname)。
我们可以使用bind函数来为一个使用在服务器端例程中的套接字赋予通信的地址和端口。
在这里我们称通信的IP地址和端口合起来构成了一个socket地址,而指定一个socket使
用特定的IP和port组合来进行通行的过程就是赋予这个socket一个地址。
要赋予socket地址,就得使用一个数据结构来指明特定的socket地址,这个数据结构就
是struct sockaddr。对它的使用我就不说了,因为这篇文档的目的是澄清概念而不是说
明使用方法。Bind函数的作用就是将这个特定的标注有socket地址信息的数据结构和
socket套接字联系起来,即赋予这个套接字一个地址。但是在具体实现上,他们两个是怎
么联系在一起的,我还不知道。
一个特定的socket的地址的生命期是bind成功以后到连接断开前。你可以建立一个
socket数据结构和socket地址的数据结构,但是在没有bind以前他们两个是没有关系
的,在bind以后他们两个才有了关系。这种关系一直维持到连接的结束,当一个连接结束
时,socket数据结构和socket地址的数据结构还都存在,但是他们两个已经没有关系
了。如果你要是用这个套接字在socket地址上重新进行连接时,需重新bind他们两个。再
注明一次,我说的这个连接是一个连接通道,而不是特定的主机之间的连接。
Bind指定的IP通常是本地IP(一般不特别指定,而使用INADDR_ANY来声明),而最主要
的作用是指定端口。在服务器端的socket进行了bind以后就是用listen来在这个socket
地址上准备进行连接。
connect:
对于客户端来说,是不会使用bind的(并不是不能用,但没什么意义),他们会通过
connet函数来建立socket和socket地址之间的关系。其中的socket地址是它想要连接的
服务器端的socket地址。在connect建立socket和socket地址两者关系的同时,它也在
尝试着建立远端的连接。
3. 建立socket连接。
对于准备建立一个连接,服务器端要两个步骤:bind, listen;客户端一个步骤:
connct。如果服务器端accept一个connect,而客户端得到了这个accept的确认,那么
一个连接就建立了。
三、客户/服务器模式模式的理解
————————————————
版权声明:本文为CSDN博主「专注DSP+ARM+FPGA」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/YEYUANGEN/article/details/6799575