socket接口是啥意思
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了socket接口是啥意思相关的知识,希望对你有一定的参考价值。
是指同一计算机不同功能层之间的通信规则称为接口。java接口作用:
1、利于代码的规范。这样做的目的一方面是为了给开发人员一个清晰的指示,告诉他们哪些业务需要实现;同时也能防止由于开发人员随意命名而导致的命名不清晰和代码混乱,影响开发效率。
2、有利于对代码进行维护。可以一开始定义一个接口,把功能菜单放在接口里,然后定义类时实现这个接口,以后要换的话只不过是引用另一个类而已,这样就达到维护、拓展的方便性。
3、保证代码的安全和严密。一个好的程序一定符合高内聚低耦合的特征,能够让系统的功能较好地实现,而不涉及任何具体的实现细节。这样就比较安全、严密一些,这一思想一般在软件开发中较为常见。 参考技术A
CPU插槽:CPU插槽主要分为Socket、Slot这两种。就是用于安装CPU的插座。目前CPU的接口都是针脚式接口,对应到主板上就有相应的插槽类型。CPU接口类型不同,在插孔数、体积、形状都有变化,所以不能互相接插。
网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket。建立网络通信连接至少要一对端口号(socket)。socket本质是编程接口(API),对TCP/IP的封装,TCP/IP也要提供可供程序员做网络开发所用的接口,这就是Socket编程接口;HTTP是轿车,提供了封装或者显示数据的具体形式;Socket是发动机,提供了网络通信的能力。Socket的英文原义是“孔”或“插座”。作为BSD UNIX的进程通信机制,取后一种意思。通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,可以用来实现不同虚拟机或不同计算机之间的通信。
后来微软等公司将它移植到了windows下,当然原来unix系统下的还是好用的。
对于socket可以这样理解:
它就是一个函数库,里面包括大量的函数和相应的数据结构,已经实现好了。
绑定多播 (UDP) 套接字是啥意思?
【中文标题】绑定多播 (UDP) 套接字是啥意思?【英文标题】:What does it mean to bind a multicast (UDP) socket?绑定多播 (UDP) 套接字是什么意思? 【发布时间】:2012-05-28 09:48:03 【问题描述】:我在具有多个网络接口的主机之间使用多播 UDP。 我正在使用 boost::asio,并且对接收器必须进行的 2 个操作感到困惑:绑定,然后加入组。
为什么需要在绑定期间指定接口的本地地址,当您对加入的每个多播组执行此操作时?
关于多播端口的姐妹问题:由于在发送期间,您发送到多播地址和端口,为什么在订阅多播组期间,您只指定地址,而不是端口 - 在令人困惑的绑定调用。
注意:“join-group”是setsockopt(IP_ADD_MEMBERSHIP)
的包装器,据记载,可以在同一个套接字上多次调用它来订阅不同的组(通过不同的网络?)。因此,每次订阅组时放弃绑定调用并指定端口是非常有意义的。
在我看来,总是绑定到“0.0.0.0”并在加入组时指定接口地址,效果很好。困惑。
【问题讨论】:
【参考方案1】:在接收多播时绑定 UDP 套接字意味着指定从其接收数据的地址和端口(不是本地接口,如 TCP 接受器绑定的情况)。在这种情况下指定的地址具有过滤作用,即套接字将只接收发送到该多播地址和端口的数据报,无论套接字随后加入了哪些组。这解释了为什么当绑定到 INADDR_ANY (0.0.0.0) 时我收到发送到我的多播组的数据报,而当绑定到任何本地接口时我没有收到任何内容,即使数据报是在该接口的网络上发送的对应。
引自 UNIX® Network Programming Volume 1, Third Edition:The Sockets Networking API by W.R Stevens。 21.10。发送和接收
[...] 我们希望接收套接字绑定多播组并 端口,比如 239.255.1.2 端口 8888。(回想一下,我们可以只绑定 通配符IP地址和端口8888,但绑定多播地址 阻止套接字接收任何其他可能的数据报 到达目的地为 8888 端口。)然后我们希望接收套接字 加入多播组。发送套接字将发送数据报到 同样的多播地址和端口,比如 239.255.1.2 端口 8888。
【讨论】:
做这个实验:在同一个应用程序中 - 创建 2 个套接字,将每个套接字加入不同的组。向两个组发送流量(在相同的端口号上!) - 如果您在绑定时未设置地址,您将获得两个组的流量,我认为 ... @nhed:在 Linux 上,它甚至不必在同一个进程中。绑定到 0.0.0.0 时,您将接收到该端口的所有多播流量,您和主机上的其他进程为其添加了组成员身份。 @JohannesOvermann,同意。我只是提出一个简单的测试来证明 OP 断言always binding to "0.0.0.0" and specifying the interface address when joining the group, works very well
是错误的
为什么错了?注意:我对“工作得很好”的意思不是很明确。我的意思是绑定到“0.0.0.0”帮助我接收流量,而不是绑定到发送流量的网络的本地接口 IP,这没有帮助。接受的答案解释了为什么会这样。【参考方案2】:
“绑定”操作基本上是说,“使用此本地 UDP 端口发送和接收数据。换句话说,它分配该 UDP 端口供您的应用程序独占使用。(对于 TCP 套接字也是如此)。
当您绑定到“0.0.0.0” (INADDR_ANY
) 时,您基本上是在告诉 TCP/IP 层使用所有可用的适配器进行侦听并选择最佳适配器进行发送。这是大多数套接字代码的标准做法。唯一不会为 IP 地址指定 0 的情况是,当您想在特定的网络适配器上发送/接收时。
同样,如果您在绑定期间指定端口值为 0,操作系统将为该套接字分配一个随机可用的端口号。因此,我希望 UDP 多播,您绑定到特定端口号上的 INADDR_ANY,预计多播流量将发送到该端口号。
需要“加入多播组”操作 (IP_ADD_MEMBERSHIP
),因为它基本上告诉您的网络适配器不仅要侦听目标 MAC 地址是您自己的以太网帧,它还告诉以太网适配器 (NIC ) 以侦听 IP 多播流量以及相应的多播以太网地址。每个多播 IP 映射到一个多播以太网地址。当您使用套接字发送到特定的多播 IP 时,以太网帧上的目标 MAC 地址设置为多播 IP 的相应多播 MAC 地址。当您加入多播组时,您将 NIC 配置为侦听发送到同一 MAC 地址的流量(除了它自己的)。
如果没有硬件支持,多播不会比普通广播 IP 消息更有效。加入操作还告诉您的路由器/网关转发来自其他网络的多播流量。 (有人记得 MBONE 吗?)
如果您加入多播组,则该 IP 地址上所有端口的所有多播流量都将由 NIC 接收。只有发往您的绑定侦听端口的流量才会通过 TCP/IP 堆栈传递到您的应用程序。关于为什么在多播订阅期间指定端口 - 这是因为多播 IP 就是这样 - 仅限 IP。 “端口”是上层协议(UDP 和 TCP)的属性。
您可以阅读有关多播 IP 地址如何映射到各个站点的多播以太网地址的更多信息。 The Wikipedia article 几乎是最好的:
IANA 拥有 OUI MAC 地址 01:00:5e,因此是多播 使用以太网 MAC 地址范围传送数据包 01:00:5e:00:00:00 - 01:00:5e:7f:ff:ff。这是 23 位可用 地址空间。第一个八位字节 (01) 包括广播/组播 少量。映射28位组播IP地址的低23位 进入 23 位可用的以太网地址空间。
【讨论】:
感谢您的关注,塞尔比。所以使用 bind(0.0.0.0) 是相关的,因为它指定了接收传入 unicast UDP 数据包的接口?我在绑定时尝试了除 0.0.0.0 以外的设置,但没有任何效果(甚至不是发送多播流量的网络的特定接口)。我还是不明白 bind() 地址的含义。 小记,对于TCP来说bind(interfAddr, port)
做了什么很清楚。它只接受来自该特定网络的连接,我已经验证这是正确的。但是对于 UDP 套接字,绑定地址与 IP_ADD_MEMBERSHIP 的第二个参数似乎是多余的。不完全是多余的,因为设置它似乎不起作用 - 只有 0.0.0.0 有效。
不确定您所说的“没有任何效果”是什么意思。发布一些演示问题的代码。至于冗余问题 - 我想您可以绑定到所有适配器(INADDR_ANY == 0.0.0.0),然后在特定接口上进行多播注册。我怀疑他们只是希望界面灵活。请阅读此链接的第 6.4 节 - tldp.org/HOWTO/Multicast-HOWTO-6.html,关于为什么需要传递接口的类似讨论。
“没有任何作用”我的意思是在绑定 UDP 套接字时,除了 INADDR_ANY (0.0.0.0) 之外的任何地址都不适合(甚至不是多播流量到达机器的接口地址,即加入组时指定为第二个参数的那个)。绑定过程中没有错误,只是read()
没有结果(永远挂起)。
这似乎不适用于多播接收器。这里的IP不是接口。它可以是 ANY,也可以是多播组地址。【参考方案3】:
更正What does it mean to bind a multicast (udp) socket?,只要它在以下引用部分正确:
“绑定”操作基本上是说,“使用这个本地 UDP 端口发送和接收数据。换句话说,它为您的应用程序分配独占使用的 UDP 端口
有一个例外。如果应用了SO_REUSEADDR
选项,多个应用程序可以共享同一个端口进行侦听(通常它对多播数据报具有实用价值)。例如
int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); // create UDP socket somehow
...
int set_option_on = 1;
// it is important to do "reuse address" before bind, not after
int res = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char*) &set_option_on,
sizeof(set_option_on));
res = bind(sock, src_addr, len);
如果多个进程进行了这种“重用绑定”,那么在该共享端口上接收到的每个 UDP 数据报都将被传递到每个进程(提供与多播流量的自然连接)。
以下是有关在某些情况下发生的情况的更多详细信息:
尝试任何绑定(“独占”或“重用”)到空闲端口都会成功
如果端口已经“重用绑定”,则尝试“独占绑定”将失败
如果某些进程保持“独占绑定”,则尝试“重用绑定”将失败
【讨论】:
【参考方案4】:区分 SENDING 多播套接字和 RECEIVING 多播套接字也很重要。
我同意上面关于接收多播套接字的所有答案。 OP 指出将 RECEIVING 套接字绑定到接口没有帮助。 但是,需要将多播 SENDING 套接字绑定到接口。
对于多宿主服务器上的 SENDING 多播套接字,非常为要发送到的每个接口创建一个单独的套接字。应该为每个接口创建一个绑定的 SENDING 套接字。
// This is a fix for that bug that causes Servers to pop offline/online.
// Servers will intermittently pop offline/online for 10 seconds or so.
// The bug only happens if the machine had a DHCP gateway, and the gateway is no longer accessible.
// After several minutes, the route to the DHCP gateway may timeout, at which
// point the pingponging stops.
// You need 3 machines, Client machine, server A, and server B
// Client has both ethernets connected, and both ethernets receiving CITP pings (machine A pinging to en0, machine B pinging to en1)
// Now turn off the ping from machine B (en1), but leave the network connected.
// You will notice that the machine transmitting on the interface with
// the DHCP gateway will fail sendto() with errno 'No route to host'
if ( theErr == 0 )
// inspired by 'ping -b' option in man page:
// -b boundif
// Bind the socket to interface boundif for sending.
struct sockaddr_in bindInterfaceAddr;
bzero(&bindInterfaceAddr, sizeof(bindInterfaceAddr));
bindInterfaceAddr.sin_len = sizeof(bindInterfaceAddr);
bindInterfaceAddr.sin_family = AF_INET;
bindInterfaceAddr.sin_addr.s_addr = htonl(interfaceipaddr);
bindInterfaceAddr.sin_port = 0; // Allow the kernel to choose a random port number by passing in 0 for the port.
theErr = bind(mSendSocketID, (struct sockaddr *)&bindInterfaceAddr, sizeof(bindInterfaceAddr));
struct sockaddr_in serverAddress;
int namelen = sizeof(serverAddress);
if (getsockname(mSendSocketID, (struct sockaddr *)&serverAddress, (socklen_t *)&namelen) < 0)
DLogErr(@"ERROR Publishing service... getsockname err");
else
DLog( @"socket %d bind, %@ port %d", mSendSocketID, [NSString stringFromIPAddress:htonl(serverAddress.sin_addr.s_addr)], htons(serverAddress.sin_port) );
如果不进行此修复,多播发送将间歇性地得到 sendto() errno 'No route to host'。 如果有人能解释为什么拔掉 DHCP 网关会导致 Mac OS X 多播发送套接字混淆,我很想听听。
【讨论】:
很好的答案,解决我关于多播的问题。以上是关于socket接口是啥意思的主要内容,如果未能解决你的问题,请参考以下文章