发送和接收数据包

发送和接收数据包

原文:Game Networking系列,作者是Glenn Fiedler,专注于游戏网络编程相关工作多年。

概述

在之前的网游中的网络编程系列1:UDP vs. TCP中(推荐先看前面那篇),我们经过讨论得出:网游中传输数据应该使用UDP而不是TCP。我们选择UDP是为了不需要等待重发数据包,从而达到数据的实时性。

注意,因为接下来英文原文中所有的代码是C++写的,而我是个pythoner,我的计划是:通过理解文章,我用python实现UDP收发数据包、虚拟连接(原文后两章的内容),在前面的基础上,最后实现:在UDP上实现可靠、有序、非阻塞的传输(当然,也可以直接看原文,连接已经在下面给出)。

所以,我重新规划了下文章的结构,后面的文章我就把它拆分成下面几章:

  1. 使用UDP发送和接收数据包
  2. 非阻塞socket
  3. 在UDP上建立虚拟连接
  4. 在UDP上实现可靠、有序、非阻塞的传输。

一、发送和接收数据包

原文:Sending and Receiving Packets

在python中,内建标准库包含了socket,所以我们直接调用标准库socket,写两个脚本,Server代表服务器,Client代表客户端,代码如下:

UDPserver.py脚本

# coding:utf-8
import socket
UDP_IP = ‘127.0.0.1‘
UDP_PORT = 10080

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind((UDP_IP, UDP_PORT))
print ‘准备接收内容。‘
while 1:
    data, addr = sock.recvfrom(1024)  # 设置接收数据包的缓存区为1024byte,如果数据包大于这个值,则数据包不会接收大于缓冲区设定值的数据包。
    print ‘从{ip}:{port},接收到内容:{data}‘.format(ip=addr[0],
                                                  port=addr[1], data=data)

UDPclient.py脚本

# coding:utf-8
import socket

UDP_IP = ‘‘
UDP_PORT = 10080
MESSAGE = ‘Hello, world!‘

print ‘UDP 目标IP:‘, UDP_IP
print ‘UDP 目标端口:‘, UDP_PORT
print ‘发送的内容:‘, MESSAGE

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.sendto(MESSAGE, (UDP_IP, UDP_PORT))

上面的代码有不懂的地方,可以参照我写的初探socket文章

运行效果:

强调几点:

  1. udp socket发送数据包的时候,不保证数据包是否发送到目的计算机。也就是说:不运行UDPserver.py脚本,先运行UDPclient.py脚本,并不报错。
  2. udp socket 每次发送数据包的时候需要指定IP地址和端口
  3. udp socket 接收数据可以获得发送数据包的计算机的IP和端口
  4. udp socket 不会接收大于缓存区的数据包(所以注意:发送时数据包的大小)

最后,可以对照着初探socket中的tcp socket例子,思考上面说的几点。

TODO

未完待续,本来这章还需要设置非阻塞socket,我觉得如果不说I/O多路复用模型,就不是很好理解设置成非阻塞有什么用。所以,我就把非阻塞socket单弄出来,放在下一章中。

参考

时间: 2024-10-26 13:34:21

发送和接收数据包的相关文章

纯 java 实现 Http 资源读取工具,支持发送和接收数据,不依赖任何第三方 jar 包

原文:纯 java 实现 Http 资源读取工具,支持发送和接收数据,不依赖任何第三方 jar 包 源代码下载地址:http://www.zuidaima.com/share/1550463379950592.htm 纯 java 实现 Http 资源读取工具,支持发送和接收数据,不依赖任何第三方 jar 包 1. 抓取指定 URL 的资源,可以作为流,也可以作为 String 2. 向指定 URL POST 数据,模拟表单提交. 例如:你想模拟 XXX 自动登陆,然后再发表心情.签名之类的 3

010 使用netmap函数接管网卡,接收数据包,回应ARP请求

一.本文目的: 上一节中,我们已经在CentOS 6.7 上安装好了netmap,也能接收和发送包了,这节我们来调用netmap中的API,接管网卡,对网卡上收到的数据包做分析,并回应ARP请求. 二.netmap API简要介绍: 1.netmap API 主要包含在两个头文件中:netmap.h和netmap_user.h.在netmap/sys/net/目录下,其中netmap_user.h调用netmap.h. 2.netmap API一共七八个函数调用:nm_open()生成文件描述符

Netty——高级发送和接收数据handler处理器

netty发送和接收数据handler处理器 主要是继承 SimpleChannelInboundHandler 和 ChannelInboundHandlerAdapter 一般用netty来发送和接收数据都会继承SimpleChannelInboundHandler和ChannelInboundHandlerAdapter这两个抽象类,那么这两个到底有什么区别呢? 其实用这两个抽象类是有讲究的,在客户端的业务Handler继承的是SimpleChannelInboundHandler,而在服

udp网络程序-发送、接收数据

1. udp网络程序-发送数据 创建一个基于udp的网络程序流程很简单,具体步骤如下: 创建客户端套接字 发送/接收数据 关闭套接字 代码如下: #coding=utf-8 from socket import * # 1. 创建udp套接字 udp_socket = socket(AF_INET, SOCK_DGRAM) # 2. 准备接收方的地址 # '192.168.1.103'表示目的ip地址 # 8080表示目的端口 dest_addr = ('192.168.1.103', 8080

socket 错误之:OSError: [WinError 10057] 由于套接字没有连接并且(当使用一个 sendto 调用发送数据报套接字时)没有提供地址,发送或接收数据的请求没有被接受。

出错的代码 #server端 import socket import struct sk=socket.socket() sk.bind(('127.0.0.1',8080)) sk.listen() conn,addr=sk.accept() str_len1=struct.unpack('i',conn.recv(4))[0] print(sk.recv(str_len1)) str_len2=struct.unpack('i',conn.recv(4))[0] print(sk.recv

Android Socket 发送与接收数据问题: 发送后的数据接收到总是粘包

先说明一下粘包的概念: 发送时是两个单独的包.两次发送,但接收时两个包连在一起被一次接收到.在以前 WinCE 下 Socket 编程,确实也要处理粘包的问题,没想到在 Android 下也遇到了.首先想从发送端能否避免这样的问题,例如: (1) 调用强制刷数据完成发送的函数:(2) 设置发送超时.1 先试了调用 flush() 函数,但运行后现象依旧2 设置发送超时是 Windows 平台的做法,但在 Android 平台下是否有类似的设置呢?查看 Socket 类的实现代码:java.net

OOBInline属性为false,server接收了client通过sendUrgentData 发送的紧急数据包

 前几天前置上线遇到一问题,大体情况是这样有一个加密服务,对外暴露tcp通讯接口,client端建立连接池,启N个连接(长连接),每次报文通讯之前先通过client端的sendUrgentData(0XFF)方法发送心跳包,用以检测信路是否正常.然后计算待发送报文的长度,将其转换成byte拼在发送报文前面(3字节长)发送报文,服务端read3字节报文并将其转换成报文长度,再根据该长度read定长的报文.测试环境OK没啥问题,上线时出问题了,每次读取的报文长度计算出来为16711680,最后发

解决WinSock中发送、接收多包问题

最近在写自己的开发库写到Socket时遇到一个很头疼的问题,那就是在发送时发送内容可能会比缓冲区大,而在接收时又不好判断什么时候接收完数据.所以写了一种发送时分割发送和分包接收后拼接的解决方案.而接收时判断数据是否传输结束,我用了select.这里以阻塞式为例子. 首先,我们需要定义一个常量,那就是我们分包时每个包的大小.如下: #define EACH_PACK_SIZE 1024 // 单个数据包大小 在发送时,我采用了分割字符串进行分包发送的方法发送数据. bool SendPacket(

java——UDP发送和接收数据

package com.socket; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.net.SocketException; import java.net.UnknownHostException; /** * 需求: 通过UDP传输方式,将一段文字发送出去 * 1.建立ud