UNIX网络编程:UDP 的connect函数(改进版)

上一篇我们提到,除非套接字已连接,否则异步错误是不会返回到UDP套接字的。我们确实可以给UDP套接字调用connect,然而这样做的结果却与TCP连接大相径庭:没有三次握手。内核只是检查是否存在立即可知的错误(例如一个显然不可达的目的地),记录对端的IP地址和端口号(取自传递给connect的套接字地址结构),然后立即返回到调用进程。

有了这个能力后,我们必须区分:

(1)未连接UDP套接字,新创建UDP套接字默认如此;

(2)已连接UDP套接字,对UDP套接字调用connect的结果。

对于已连接UDP套接字,与默认的未连接UDP套接字相比,发生了三个变化:

(1)我们再也不能给输出操作指定目的IP地址和端口号。也就是说,我们不使用sendto,而改用write或send。写到已连接UDP套接字上的任何内容都自动发送到由connect指定的协议地址(例如IP地址和端口号)。(其实我们可以给已连接UDP套接字调用sendto,但是不能指定目的地址。sendto的第五个参数必须为空,第六个参数应该为0)。

后面有在ubuntu 10.04系统下的验证。

(2)我们不必使用recvfrom以获悉数据报的发送者,而改用read,recv或recvmsg。在一个已连接UDP套接字上,由内核为输入操作返回的数据报只有那些来自connect所指定协议地址的数据报。(确切的说,一个已连接的UDP套接字仅仅与一个IP地址交换数据报,因为connect到多播或广播地址是可能的)。

(3)由已连接的UDP套接字引发的异步错误会返回给他们所在的进程,而未连接UDP套接字不接受任何异步错误。

应用进程首先调用connect指定对端的IP地址和端口号,然后使用read和write与对端进程交换数据。来自任何其他IP地址或端口的数据报(上中我们用“???”表示)不投递给这个已连接套接字,因为他们要么源IP地址要么源UDP端口不与该套接字connect到的协议地址相匹配。这些数据报可能投递给同一个主机上的其他某个UDP套接字。如果没有相匹配的其他套接字,UDP将丢弃他们并生成相应的ICMP端口不可达错误。

1.给一个UDP套接字多次调用connect

拥有一个已连接UDP套接字的进程可出于下列两个目的之一再次调用connect:

指定新的IP地址和端口号;

断开套接字。

第一个目的(即给一个已连接UDP套接字指定新的对端)不同于TCP套接字中的connect的使用:对于TCP套接字,connect只能调用一次。

为了断开一个已UDP套接字连接,我们再次调用connect时把套接字地址结构的地址族成员(sin_family)设置为AF_UNSPEC。使套接字断开连接的是在已连接UDP套接字上调用connect的进程。

查看本栏目更多精彩内容:http://www.bianceng.cnhttp://www.bianceng.cn/OS/unix/

时间: 2024-12-31 22:03:45

UNIX网络编程:UDP 的connect函数(改进版)的相关文章

《UNIX网络编程 卷1:套接字联网API(第3版)》——8.11 UDP的connect函数

8.11 UDP的connect函数 在8.9节结尾我们提到,除非套接字已连接,否则异步错误是不会返回到UDP套接字的.我们确实可以给UDP套接字调用connect(4.3节),然而这样做的结果却与TCP连接大相径庭:没有三路握手过程.内核只是检查是否存在立即可知的错误(例如一个显然不可达的目的地),记录对端的IP地址和端口号(取自传递给connect的套接字地址结构),然后立即返回到调用进程. 给connect函数重载(overload)UDP套接字的这种能力容易让人混淆.如果使用约定,令so

《UNIX网络编程 卷1:套接字联网API(第3版)》——导读

**前言**本书面向的读者是那些希望自己编写的程序能使用称为套接字(socket)的API进行彼此通信的人.有些读者可能已经非常熟悉套接字了,因为这个模型几乎已经成了网络编程的同义词,但有些读者可能仍需要从头开始学习.本书想达到的目标是向大家提供网络编程指导.这些内容不仅适用于专业人士,也适用于初学者:不仅适用于维护已有代码,也适用于开发新的网络应用程序:此外,还适用于那些只是想了解一下自己系统中网络组件的工作原理的人. 书中的所有示例都是在Unix系统上测试通过的真实的.可运行的代码.但是,考

unix网络编程问题(初学者)

问题描述 unix网络编程问题(初学者) 除了头文件和打印外,我都是照着书敲的,但是结果不对,希望帮我解决,谢谢啦!!!书上的正确结果是一串表示时间的字符 问题:connect error 在建立服务器的连接出错输入:./get_tima 192.168.154.130(ip地址我用ifconfig得到的,我也用127.0.0.1做过一样得不到想要的结果)结果:connect errorread error 出处:unix网络编程 1.2-一个简单的时间获取客户程序 #include#inclu

select-调试信息无法打印 unix网络编程

问题描述 调试信息无法打印 unix网络编程 如代码注释信息所示,应该是缓冲区的问题,但是stderr是无缓冲区的,而且也使用了fflush函数,也没用.希望能有人指点指点,谢谢 #include "globle.h" #define port 8082 int main( int argc, char *argv[] ){ fprintf(stderr, "11111111111n");//无法打印 fflush(stdout); int listenfd,soc

UNIX网络编程之旅-配置unp.h头文件环境

最近在学习Unix网络编程(UNP),书中steven在处理网络编程时只用了一个#include "unp.h"  相当有个性并且也很便捷 于是我把第三版的源代码编译实现了这个过程,算是一种个性化的开发环境的搭建吧,顺便把过程记录下来,以便自己以后查阅.   首先去网上找到源代码包unpv.13e.tar.gz 一找一大堆 解压缩到你的某个目录,unpv13e里面大致有这些目录 ├── aclocal.m4 ├── advio ├── bcast ├── config.guess ├─

UNIX网络编程:UDP缺乏流量控制(改进版)

现在我们查看无任何流量控制的UDP对数据报传输的影响.首先我们把dg_cli函数修改为发送固定数目的数据报,并不再从标准输入读.如下,它写2000个1400字节大小的UDP数据报给服务器. 客户端程序cli.c: #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #inc

UNIX网络编程:UDP 中的外出接口的确定

已连接UDP套接字还可用来确定用于特定目的地的外出接口.这是由connect函数应用到UDP套接字时的一个副作用造成的:内核选择本地IP地址.这个本地IP地址通过为目的IP地址搜索路由表得到外出接口,然后选用该接口的主IP地址而选定. 注意:getsockname函数调用的位置. #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h>

UNIX网络编程:I/O复用:select和poll函数

我们看到TCP客户同时处理两个输入:标准输入和TCP套接字.我们遇到的问题是就在客户阻塞于(标准输入上)fgets调用,服务器进程会被杀死.服务器TCP虽然正确的给客户TCP发送了一个FIN,但是既然客户进程正阻塞于从标准输入读入的过程,它将看不到这个EOF,直到从套接字读时为止(可能额已过了很长时间).这样的进程需要一种预先告知内核的能力,使得内核一旦发现进程指定的一个或多个I/O条件就绪(也就是说输入已准备好被读入,或者描述符已能承接更多的输出),它就通知进程.这个能力称为I/O复用,是由s

《UNIX网络编程 卷1:套接字联网API(第3版)》——第8章 基本UDP套接字编程 8.1概述

第8章 基本UDP套接字编程 8.1 概述 在使用TCP编写的应用程序和使用UDP编写的应用程序之间存在一些本质差异,其原因在于这两个传输层之间的差别:UDP是无连接不可靠的数据报协议,非常不同于TCP提供的面向连接的可靠字节流.然而相比TCP,有些场合确实更适合使用UDP,我们将在22.4节探讨这个设计选择.使用UDP编写的一些常见的应用程序有:DNS(域名系统).NFS(网络文件系统)和SNMP(简单网络管理协议). 图8-1给出了典型的UDP客户/服务器程序的函数调用.客户不与服务器建立连

UNIX网络编程:fcntl函数

fcntl函数提供了与网络编程相关的如下特性: 非阻塞式I/O.  通过使用F_SETFL命令设置O_NONBLOCK文件状态标志,我们可以把一个套接字设置为非阻塞型. 信号驱动式I/O. 通过使用F_SETFL命令设置O_ASYNC文件状态标志,我们可以把一个套接字设置成O_ASYNC,一旦其状态发生变化,内核就产生一个SIGIO信号. F_SETOWN命令允许我们指定用于接收SIGIO和SIGURG信号的套接字属主(进程ID或进程组ID).其中SIGIO信号是套接字被设置为信号驱动式I/O型