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,如需转载请自行联系原作者
相关文章
|
23天前
|
存储 安全 Linux
|
25天前
|
Linux Shell 数据安全/隐私保护
|
2月前
|
Linux 编译器 C语言
【Linux快速入门(一)】Linux与ROS学习之编译基础(gcc编译)
【Linux快速入门(一)】Linux与ROS学习之编译基础(gcc编译)
|
2月前
|
Linux 网络安全
Linux虚拟机与主机和Xshell的连接问题解决
Linux虚拟机与主机和Xshell的连接问题解决
81 1
|
2月前
|
网络协议 Linux
linux学习之套接字通信
Linux中的套接字通信是网络编程的核心,允许多个进程通过网络交换数据。套接字提供跨网络通信能力,涵盖本地进程间通信及远程通信。主要基于TCP和UDP两种模型:TCP面向连接且可靠,适用于文件传输等高可靠性需求;UDP无连接且速度快,适合实时音视频通信等低延迟场景。通过创建、绑定、监听及读写操作,可以在Linux环境下轻松实现这两种通信模型。
39 1
|
2月前
|
Linux 开发工具
【Linux快速入门(二)】Linux与ROS学习之编译基础(make编译)
【Linux快速入门(二)】Linux与ROS学习之编译基础(make编译)
|
3月前
|
NoSQL Linux Redis
linux安装单机版redis详细步骤,及python连接redis案例
这篇文章提供了在Linux系统中安装单机版Redis的详细步骤,并展示了如何配置Redis为systemctl启动,以及使用Python连接Redis进行数据操作的案例。
75 2
|
3月前
|
Unix Linux 网络安全
python中连接linux好用的模块paramiko(附带案例)
该文章详细介绍了如何使用Python的Paramiko模块来连接Linux服务器,包括安装配置及通过密码或密钥进行身份验证的示例。
99 1
|
2月前
|
关系型数据库 MySQL Linux
Navicat 连接 Windows、Linux系统下的MySQL 各种错误,修改密码。
使用Navicat连接Windows和Linux系统下的MySQL时可能遇到的四种错误及其解决方法,包括错误代码2003、1045和2013,以及如何修改MySQL密码。
224 0
|
3月前
|
关系型数据库 MySQL 数据库
docker启动mysql多实例连接报错Can’t connect to local MySQL server through socket ‘/var/run/mysqld/mysqld.sock’
docker启动mysql多实例连接报错Can’t connect to local MySQL server through socket ‘/var/run/mysqld/mysqld.sock’
206 0