网络编程3

1.1  udp网络程序-发送数据

Socket函数

mySocket = socket(family, type)

函数socket()的参数family用于设置网络通信的域,函数socket()根据这个参数选择通信协议的族。通信协议族在文件sys/socket.h中定义。


函数socket()的参数type用于设置套接字通信的类型,主要有SOCKET_STREAM(流式套接字)、SOCK——DGRAM(数据包套接字)等。

并不是所有的协议族都实现了这些协议类型,例如,AF_INET协议族就没有实现SOCK_SEQPACKET协议类型。


创建一个udp客户端程序的流程是简单,具体步骤如下:

1.创建客户端套接字

2.发送/接收数据

3.关闭套接字

代码如下:

from socket import *

#1.创建套接字

udpSocket = socket(AF_INET, SOCK_DGRAM)

#2.准备接收方的地址

sendAddr = ('192.168.11.74', 7788)

#3.从键盘获取数据

sendData = input("请输入要发送的数据:")

#4.发送数据到指定的电脑上

udpSocket.sendto(sendData.encode('gbk'), sendAddr)

#5.关闭套接字

udpSocket.close()

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

#coding=utf-8

fromsocketimport*

#1.创建套接字

udpSocket = socket(AF_INET, SOCK_DGRAM)

#2.准备接收方的地址

sendAddr = ('192.168.1.103',8080)

#3.从键盘获取数据

sendData = input("请输入要发送的数据:")

#4.发送数据到指定的电脑上

udpSocket.sendto(sendData, sendAddr)

#5.等待接收对方发送的数据

recvData = udpSocket.recvfrom(1024)# 1024表示本次接收的最大字节数

#6.显示对方发送的数据

print(recvData)

#7.关闭套接字

udpSocket.close()

1.3 udp网络程序-端口问题

会变的端口号

重新运行多次脚本,然后在“网络调试助手”中,看到的现象如下:


说明:

·每重新运行一次网络程序,上图中红圈中的数字,不一样的原因在于,这个数字标识这个网络程序,当重新运行时,如果没有确定到底用哪个,系统默认会随机分配

·记住一点:这个网络程序在运行的过程中,这个就唯一标识这个程序,所以如果其他电脑上的网络程序如果想要向此程序发送数据,那么就需要向这个数字(即端口)标识的程序发送即可

1.4 udp 绑定信息

1.绑定信息

还记得在上一节课中,如果一个网络程序在每次运行的时候端口是随机变化的么?

一般情况下,在一天电脑上运行的网络程序有很多,而各自用的端口号很多情况下不知道,为了不与其他的网络程序占用同一个端口号,往往在编程中,udp的端口号一般不绑定

但是如果需要做成一个服务器端的程序的话,是需要绑定的,想想看这又是为什么呢?

如果报警电话每天都在变,想必世界就会乱了,所以一般服务性的程序,往往需要一个固定的端口号,这就是所谓的端口绑定

2.绑定示例

#coding=utf-8

fromsocketimport*

#1.创建套接字

udpSocket = socket(AF_INET, SOCK_DGRAM)

#2.绑定本地的相关信息,如果一个网络程序不绑定,则系统会随机分配

bindAddr = ('',7788)# ip地址和端口号,ip一般不用写,表示本机的任何一个ip

udpSocket.bind(bindAddr)

#3.等待接收对方发送的数据

recvData = udpSocket.recvfrom(1024)# 1024表示本次接收的最大字节数

#4.显示接收到的数据

print(recvData)

#5.关闭套接字

udpSocket.close()

总结

·一个udp网络程序,可以不绑定,此时操作系统会随机进行分配一个端口,如果重新运行次程序端口可能会发生变化

·一个udp网络程序,也可以绑定信息(ip地址,端口号),如果绑定成功,那么操作系统用这个端口号来进行区别收到的网络数据是否是此进程的

1.5 udp网络通信过程


1.6 udp应用:echo服务器

参考代码

#coding=utf-8

fromsocketimport*

#1.创建套接字

udpSocket = socket(AF_INET, SOCK_DGRAM)

#2.绑定本地的相关信息

bindAddr = ('',7788)# ip地址和端口号,ip一般不用写,表示本机的任何一个ip

udpSocket.bind(bindAddr)

num =1

whileTrue:

#3.等待接收对方发送的数据

recvData = udpSocket.recvfrom(1024)# 1024表示本次接收的最大字节数

#4.将接收到的数据再发送给对方

udpSocket.sendto(recvData[0], recvData[1])

#5.统计信息

print('已经将接收到的第%d个数据返回给对方,内容为:%s'%(num,recvData[0]))

num+=1

#5.关闭套接字

udpSocket.close()

1.7 udp应用:聊天室

参考代码

fromsocketimport*

fromtimeimportctime

#1.创建套接字

udpSocket = socket(AF_INET, SOCK_DGRAM)

#2.绑定本地的相关信息

bindAddr = ('',7788)# ip地址和端口号,ip一般不用写,表示本机的任何一个ip

udpSocket.bind(bindAddr)

whileTrue:

#3.等待接收对方发送的数据

recvData = udpSocket.recvfrom(1024)# 1024表示本次接收的最大字节数

#4.打印信息

print('【%s】%s:%s'%(ctime(),recvData[1][0],recvData[0]))

#5.关闭套接字

udpSocket.close()

1.8 udp广播

网络编程中的广播

importsocket, sys

dest = ('',7788)

#创建udp套接字

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

#对这个需要发送广播数据的套接字进行修改设置,否则不能发送广播数据

s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST,1)

#以广播的形式发送数据到本网络的所有电脑中

s.sendto("Hi", dest)

print("等待对方回复(按ctrl+c退出)")

whileTrue:

(buf, address) = s.recvfrom(2048)

print("Received from %s: %s"% (address, buf))

1.9 udp总结

1. udp是TCP/IP协议族中的一种协议能够完成不同机器上的程序间的数据通信

2. udp服务器、客户端

·udp的服务器和客户端的区分:往往是通过请求服务和提供服务来进行区分

·请求服务的一方称为:客户端

·提供服务的一方称为:服务器

3. udp绑定问题

·一般情况下,服务器端,需要绑定端口,目的是为了让其他的客户端能够正确发送到此进程

·客户端,一般不需要绑定,而是让操作系统随机分配,这样就不会因为需要绑定的端口被占用而导致程序无法运行的情况

1.10 udp模拟qq

1.任务要求:

·使用多线程完成一个全双工的QQ聊天程序

单工、半双工、全双工

单工数据传输只支持数据在一个方向上传输;

半双工数据传输允许数据在两个方向上传输,但是,在某一时刻,只允许数据在一个方向上传输,它实际上是一种切换方向的单工通信;

全双工数据通信允许数据同时在两个方向上传输,因此,全双工通信是两个单工通信方式的结合,它要求发送设备和接收设备都有独立的接收和发送能力.

2.参考代码

from threading import Thread

from socket import *

# 1.收数据,然后打印

def recvData():

while True:

recvInfo = udpSocket.recvfrom(1024)

print(">>%s:%s" % (str(recvInfo[1]), recvInfo[0]))

# 2.检测键盘,发数据

def sendData():

while True:

sendInfo = input("<<")

udpSocket.sendto(sendInfo.encode("gb2312"), (destIp, destPort))

udpSocket = None

destIp = ""

destPort = 0

def main():

global udpSocket

global destIp

global destPort

destIp = input("对方的ip:")

destPort = int(input("对方的ip:"))

udpSocket = socket(AF_INET, SOCK_DGRAM)

udpSocket.bind(("", 4567))

tr = Thread(target=recvData)

ts = Thread(target=sendData)

tr.start()

ts.start()

tr.join()

ts.join()

if __name__ == "__main__":

main()

1.11 TFTP客户端

1. TFTP协议介绍

TFTP(Trivial File Transfer Protocol,简单文件传输协议)

是TCP/IP协议族中的一个用来在客户端与服务器之间进行简单文件传输的协议

特点:

·简单

·占用资源小

·适合传递小文件

·适合在局域网进行传递

·端口号为69

·基于UDP实现

2. TFTP下载过程

TFTP服务器默认监听69号端口

当客户端发送“下载”请求(即读请求)时,需要向服务器的69端口发送

服务器若批准此请求,则使用一个新的、临时的 端口进行数据传输


当服务器找到需要现在的文件后,会立刻打开文件,把文件中的数据通过TFTP协议发送给客户端

如果文件的总大小较大(比如3M),那么服务器分多次发送,每次会从文件中读取512个字节的数据发送过来

因为发送的次数有可能会很多,所以为了让客户端对接收到的数据进行排序,所以在服务器发送那512个字节数据的时候,会多发2个字节的数据,用来存放序号,并且放在512个字节数据的前面,序号是从1开始的

因为需要从服务器上下载文件时,文件可能不存在,那么此时服务器就会发送一个错误的信息过来,为了区分服务发送的是文件内容还是错误的提示信息,所以又用了2个字节 来表示这个数据包的功能(称为操作码),并且在序号的前面


因为udp的数据包不安全,即发送方发送是否成功不能确定,所以TFTP协议中规定,为了让服务器知道客户端已经接收到了刚刚发送的那个数据包,所以当客户端接收到一个数据包的时候需要向服务器进行发送确认信息,即发送收到了,这样的包成为ACK(应答包)

为了标记数据已经发送完毕,所以规定,当客户端接收到的数据小于516(2字节操作码+2个字节的序号+512字节数据)时,就意味着服务器发送完毕了

TFTP数据包的格式如下:


�O4;3�m

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,847评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,208评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,587评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,942评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,332评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,587评论 1 218
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,853评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,568评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,273评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,542评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,033评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,373评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,031评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,073评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,830评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,628评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,537评论 2 269

推荐阅读更多精彩内容

  • 一、概念 首先,理清一些概念 TCP/IP和UDP,HTTP协议,Socket 1.TCP/IP和UDP,是网络中...
    _AJH阅读 4,051评论 0 18
  • tcp/ip简介 为了把全世界的所有不同类型的计算机都连接起来,就必须规定一套全球通用的协议,为了实现互联网这个目...
    盛夏光年_49e9阅读 517评论 0 0
  • 一 、Socket 网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个 Socket。S...
    空白Null阅读 1,667评论 1 9
  • 1. G和J 当大家发G的读音时,会发现读音的末尾是发ei的音,这也不难理解,因为B/be/ 、C/se/、D/d...
    yoku酱阅读 212评论 0 2
  • Mysql 内存+后台线程 主从复制 1. Master 库中,数据变更时,写入binary Log。 2. Sl...
    郭大瞎阅读 174评论 0 0