如何发送数据包?

Q:当应用程序产生数据的时候,需要去构造数据包并发送到网络上去,但是由谁负责处理呢?

A:现代操作系统负责数据包得构造与发送,应用程序只需提供数据。 当应用程序产生数据时,应用程序将数据交给OS内核,然后在OS内核添加各层的首部,构建好数据包,然后交给网卡,发送到网络中去。

Q:应用程序如何向OS 发送数据呢?

A: OS为程序提供了一个接口,即socket API,类似于系统调用函数。

Q:通过socket API,只需要提供数据吗?

A:并不,还需要告诉OS 内核,目的端口是什么,传输层使用哪种协议(UDP/TCP),目的IP地址。

Q:为什么不需要告诉源端口?

A:因为源端口是当数据进入到OS内核时,OS会为这个应用程序随机开放一个端口,作为源端口。当服务器端收到数据,进行返回时,也从这个端口进行返回。同样源IP地址,OS内核也是选一个网卡出去,这个网卡的地址作为源IP地址。

详情可见下图:

Q:加工数据是包括什么?

A:依次包括添加传输层首部,网络层首部,所以在这里需要告诉传输层的目的端口,以及使用的协议,以及网络层的目的IP地址。然后交给网卡驱动程序,构造数据链路层头部,以及物理层。若想继续详细了解网卡的操作,可参考:网卡工作原理详解从网卡发送数据再谈TCP/IP协议—网络传输速度计算-网卡构造

了解到上述信息,知道我们要告诉OS 目的IP地址,目的端口,以及数据。

下面是使用python网络编程客户端的代码:

import  socket

ip="127.0.0.1"
port=8090
data = b"hello PsgQ"
sock=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
sock.sendto(data,(ip,port))

Q: socket函数里面的参数是什么意思?

A: socket.AF_INET表示使用IPv4。socket.SOCK_DGRAM表示传输层使用UDP。

Q:为什么data=b"hello PsgQ"?

A: 因为在网络中传输的是字节流,b前缀将字符串转换成bytes。对于英文字母可以这样转换,但对于中文字符串不行,因为b后面的字符串必须是ascii码可以表示的。若要传递中文字符串,须data=bytes('哈哈',encoding='UTF-8')

具体可参考字符串和编码

c语言版代码随后更新。

如何接收数据包?

网卡驱动程序收到数据,作出校验以及检查完相应的目的MAC地址,交到OS内核。

OS内核 网络层模块 进行解封装,查看IP的目的地址,是不是发给自己的,丢弃IP地址不是自己的数据包。然后查看传输层使用的是什么协议,假如是UDP,之后交给UDP模块处理。

UDP获得数据包后,查看目的端口,发给相应的端口。

Q:应用程序怎么去获得数据阿?

A:每个应用程序想要去接收数据,都需要与相应的端口进行绑定。比如HTTP,默认80端口,DNS默认使用53端口等。即OS内核交付给相应的端口,就意味着交付到某个应用程序(通过socket API)。相当于告诉内核,任何时候只要有数据到达这个端口,可以把数据交给我。具体过程是,OS 内核交给相应的端口的缓冲区,这个缓冲区是与端口进行绑定的。应用程序可从这个缓冲区读取数据。

实际情况可能是:当没有数据时,这个应用程序的socket API会被阻塞掉,但当数据包到达时,OS内核会去激活这个进程。

如下图:

从上述信息了解到,我们在server端要进行绑定端口,因为可能有多个网卡,每个网卡IP地址不同,所以我们也要绑定IP地址等。

下面是使用python网络编程服务器端的代码:

import  socket

ip="0.0.0.0"
port = 8090
sock=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
sock.bind((ip,port)) while True:
data,(ip,port)=sock.recvfrom(1024)
data=data.decode('ascii')
print("clinet:{},port:{}".format(ip,port))
print("Received:{}".format(data))

Q: ip ="0.0.0.0"?

A: 表示 数据包的目的地址可以是任意一个网卡的地址。

Q: data=data.decode('ascii')

A: 因为网络上使用的是字节流,前面客户端将字符串转换成了字节流,在这里使用ascii码进行解码,使字节流重又转换成字符串格式。

注意:调用bind函数 ,参数是(ip,port)

最终运行结果:

网络编程原理与UDP实现的更多相关文章

  1. Socket网络编程TCP、UDP演示样例

    Socket网络编程: 1) OSI(了解): 国际标准化组织ISO(International Orgnization for Standardization)指定了网络通信的模型:开放系统互联(O ...

  2. 网游中的网络编程3:在UDP上建立虚拟连接

    目录 网游中的网络编程系列1:UDP vs. TCP 网游中的网络编程2:发送和接收数据包 网游中的网络编程3:在UDP上建立虚拟连接 TODO 二.在UDP上建立虚拟连接 介绍 UDP是无连接的,一 ...

  3. 网络编程第三讲UDP编写

    网络编程第三讲UDP编写 一丶UDP简介 UDP是面向无连接的.就是说数据传输会丢掉.网络延时比较大的情况下.会早上丢包.例如视频通话.就是UDP UDP不需要建立建立. 下面有UDP编写流程图 下图 ...

  4. C#网络编程入门之UDP

    目录: C#网络编程入门系列包括三篇文章: (一)C#网络编程入门之UDP (二)C#网络编程入门之TCP (三)C#网络编程入门之HTTP 一.概述 UDP和TCP是网络通讯常用的两个传输协议,C# ...

  5. TCP/IP网络编程之基于UDP的服务端/客户端

    理解UDP 在之前学习TCP的过程中,我们还了解了TCP/IP协议栈.在四层TCP/IP模型中,传输层分为TCP和UDP这两种.数据交换过程可以分为通过TCP套接字完成的TCP方式和通过UDP套接字完 ...

  6. Linux Linux程序练习十一(网络编程大文件发送UDP版)

    //网络编程发送端--大文件传输(UDP) #include <stdio.h> #include <stdlib.h> #include <string.h> # ...

  7. Linux网络编程10——使用UDP实现五子棋对战

    思路 1. 通信 为了同步双方的棋盘,每当一方在棋盘上落子之后,都需要发送给对方一个msg消息,让对方知道落子位置.msg结构体如下: /* 用于发给对方的信息 */ typedef struct t ...

  8. javase的网络编程(InetAddress,UDP,TCP,URL,Socket,DatagramSocket)

    通过一段时间对java网络编程相关内容的学习,写下这篇随笔,对这一部分的知识进行梳理和总结. 网络编程 一.网络编程三要素: IP地址:网络会给每个联网的主机分配一个数字的编码地址,该地址就是IP地址 ...

  9. [网络编程] TCP、UDP区别以及TCP传输原理、拥塞避免、连接建立、连接释放总结

    TCP.UDP都是属于运输层的协议,提供端到端的进程之间的逻辑通信,而IP协议(网络层)是提供主机间的逻辑通信,应用层规定应用进程在通信时所遵循的协议.一.UDP主要特点:传输的是用户数据报协议.1. ...

随机推荐

  1. dhcp、tftp、httpd、pxe安装CentOS6.9

    虚拟机网络设置 要xshell连接虚拟机注意设置VMware Network Adapter VMnet2在同一网段 1.利用光盘配置本地yum源 [root@ZYB ~]# mount -r /de ...

  2. 分库分表的 9种分布式主键ID 生成方案,挺全乎的

    <sharding-jdbc 分库分表的 4种分片策略> 中我们介绍了 sharding-jdbc 4种分片策略的使用场景,可以满足基础的分片功能开发,这篇我们来看看分库分表后,应该如何为 ...

  3. bert做阅读理解的一个细节

    如上图所示,展示了如何用BERT来做信息抽取任务的结构图.注意一下几点即可: 1.将Question和Paragraph分别作为BERT的text1和text2输入. 2.start/end span ...

  4. 用npm安装插件时报错: fsevents@^1.0.0 (node_modules\chokidar\node_modules\fsevents)

    在做前端项目的时候执行命令: npm install --save-dev file-loader@1.1.6 --registry=https://registry.npm.taobao.org 出 ...

  5. C# 中的数字分隔符 _

    编写 C# 代码时,我们时常会用到很大的数字,例如下面定义的变量: const long loops = 50000000000; 您能快速读出这是多少吗?是不是还是会有很多人把光标定位到最后一位,然 ...

  6. .Net核心依赖项注入:生命周期和最佳实践

    在讨论.Net的依赖注入(DI)之前,我们需要知道我们为什么需要使用依赖注入 依赖反转原理(DIP): DIP允许您将两个类解耦,否则它们会紧密耦合,这有助于提高可重用性和更好的可维护性 DIP介绍: ...

  7. linux 异步I/O 信号

    if (ioctl(ngx_processes[s].channel[0], FIOASYNC, &on) == -1) { ngx_log_error(NGX_LOG_ALERT, cycl ...

  8. IP 层收发报文简要剖析5--ip报文发送2

    udp 发送ip段报文接口ip_append_data ip_append_data 函数主要用来udp 套接字以及raw套接字发送报文的接口.在tcp中发送ack 以及rest段的ip_send_u ...

  9. MYSQL 存储引擎(面)

    存储引擎是MySQL的组件,用于处理不同表类型的SQL操作.不同的存储引擎提供不同的存储机制.索引技巧.锁定水平等功能,使用不同的存储引擎,还可以获得特定的功能. 使用哪一种引擎可以灵活选择,一个数据 ...

  10. 洛谷 P2101 命运石之门的选择 (分治)

    P2101 命运石之门的选择 (分治) 介绍 El Psy Congroo 题目链接 没错,作为石头门厨,怎么能不做石头门的题呢?(在搜石头门的时 候搜到了本题) 本题作为一道分治基础练习题还是不错的 ...