Linux Socket学习--面向非连接的协议

简介:

套接口的通信有2中基本方式:面向连接和面向非连接的通信。

面向非连接指的是通信之前不需要建立连接,我们生成了一个非连接的套接口,就可以向任何愿意接受我们消息的套接口发送消息,而且每一个消息都可以被重定向到不同的套接口。

我们之前的文章中提供socketpair函数,但是我们当时没有说这个函数是使用面向连接协议来生成套接口对的。

sendto()函数介绍

    sendto函数容许我们写一个数据报,并且同时制定接受者的地址。语法如下:

#include <sys/types.h>
#include <sys/socket.h>

int sendto(const void* msg,int len, unsigned flags, const struct sockaddr* to, int tolen);

如果函数调用成功,返回值就是发送的字节数,如果调用失败,返回值就是-1.我们可以通过检查errno的值来判断错误的原因。

虽然在大多数的情况下,参数flags只需要为0,但是我们还是列出了其他的值:

image

recvfrom函数介绍

recvfrom函数使得我们能够在接受数据报的同时,也能够得到发送者的地址,函数语法如下:

#include <sys/types.h>
#include <sys/socket.h>
int recvfrom(void* buf, int len, unsigned flags, struct sockaddr* from, int* fromlen);

函数调用成功的话返回接受缓冲区所接受的字节数,如果调用失败,返回值为-1.我们可以通过检查errno的值来判断错误的原因。

    注意:如果使用函数recvfrom来接受不同的协议的数据报,那么我们就必须确定为所有可能遇到的地址族分配足够的套接口地址空间。比如地址族AF_INET和AF_LOCAL套接口地址的尺寸就不一样,通常我们可以使用c语言中的联合数据结构来解决这个问题。

   下表是recvfrom参数的flags的取值,不过通常情况下我们仅仅取值为0:

image

下面我们来编写一个UDP数据报服务器程序:

--UNDONE(此处代码有待添加)

下面这个程序是UDP客户端程序:

--UNDONE(此处代码有待添加)

如果我们在不启动服务器程序的情况下,仅仅启动客户端程序,我们会发现客户端程序可以启动,也可以生成套接口并且要求输入,甚至函数dendto的调用也是成功的,错误来源于recvfrom,这个说明了,发送一个数据报仅仅是将数据报发送出去,但并不能说明他已经被成功接收。

  在上面的例子中大家可能注意到客户端程序在生成套接口之后,并没有调用bind函数,我们知道bind函数的作用就是限制用于进行网络通信的接口,在上面的例子中省略了对bind的调用,意味着程序可以选择任何一个接口进行发送,在效果上就如同套接口被绑定了统配套接口地址,当程序相应的时候,他也可以使用结果任何一个接口来接收数据。这个时候,套接口的端口号也是通配的。

我们也可以使用bind函数明确的指出通配地址,我们可以通过INADDR_NONE来达到目的,另外为了得到一个通配的端口号,可以将端口号指定为0.所以指定IP地址和端口号分别为INADDR_NONE和0所达到的效果和不调用bind函数的效果是相同的。

现在遇到的问题是如果客户端程序的地址和端口号都是通配的,那么服务器怎么向这个套接口进行应答呢?答案是:IP地址和端口号是数据报在发送的时候才分配的。通配端口号是从目前所有可用的端口号中随机挑选的。

如果发送主机具有多个接口,而且又发送了一个数据报,那么这个数据报的原始IP地址就可能变化,总之,原始IP地址反应的是发送数据报所使用的网络接口的IP地址。


==============================================================================
本文转自被遗忘的博客园博客,原文链接:http://www.cnblogs.com/rollenholt/archive/2012/08/20/2648143.html,如需转载请自行联系原作者
相关文章
|
1月前
|
Shell Linux C语言
【Shell 命令集合 网络通讯 】Linux 关闭PPP(Point-to-Point Protocol)连接 ppp-off命令 使用指南
【Shell 命令集合 网络通讯 】Linux 关闭PPP(Point-to-Point Protocol)连接 ppp-off命令 使用指南
42 1
|
14天前
|
存储 算法 Linux
【实战项目】网络编程:在Linux环境下基于opencv和socket的人脸识别系统--C++实现
【实战项目】网络编程:在Linux环境下基于opencv和socket的人脸识别系统--C++实现
38 6
|
3天前
|
Unix Linux Windows
Linux的学习之路:3、基础指令(2)
Linux的学习之路:3、基础指令(2)
26 0
|
1月前
|
监控 网络协议 Linux
【Shell 命令集合 网络通讯 】Linux 显示网络 连接、路由表和网络接口信息 netstat命令 使用指南
【Shell 命令集合 网络通讯 】Linux 显示网络 连接、路由表和网络接口信息 netstat命令 使用指南
62 1
|
2天前
|
存储 网络协议 关系型数据库
Python从入门到精通:2.3.2数据库操作与网络编程——学习socket编程,实现简单的TCP/UDP通信
Python从入门到精通:2.3.2数据库操作与网络编程——学习socket编程,实现简单的TCP/UDP通信
|
2天前
|
监控 Linux 网络安全
Linux服务器如何查询连接服务器的IP
【4月更文挑战第15天】Linux服务器如何查询连接服务器的IP
9 1
|
3天前
|
运维 网络协议 Linux
Linux(28) Linux双网卡配置为连接到Linux主机的PC提供外网访问
Linux(28) Linux双网卡配置为连接到Linux主机的PC提供外网访问
27 1
|
3天前
|
消息中间件 Unix Linux
Linux的学习之路:17、进程间通信(1)
Linux的学习之路:17、进程间通信(1)
18 1
|
3天前
|
存储 安全 Linux
Linux的学习之路:9、冯诺依曼与进程(1)
Linux的学习之路:9、冯诺依曼与进程(1)
18 0
|
6天前
|
网络协议 安全 Linux
IDEA通过内网穿透实现固定公网地址远程SSH连接本地Linux服务器
IDEA通过内网穿透实现固定公网地址远程SSH连接本地Linux服务器