python 网络编程01

一、理解TCP基础

1.寻址

TCP要能识别远程的机器,基于TCP/IP网络的每台机器都有一个唯一的IP地址。(ip)

TCP需要知道与远程机器上运行的哪个程序通信,每个程序要使用一个唯一的端口号。(port)

因此,每个TCP连接的端点是由一个IP地址和一个端口号来唯一标识。(ip:port)

虽然有IP和端口号,TCP就能很好的工作,但是记住一串数字比较困难,由于这个原因出现了DNS。

现在想要和远程机器建立连接,可以申请连接该机器IP地址相对应的DNS(如:www.baidu.com),

DNS会提供一个IP地址,接下来就可以建立连接。

2.可靠性

TCP是一个可靠的协议,除非整个网络出现问题,否则数据将被完好的按原样正确的传送到另外一端。

这个可靠性通过以下规则实现:

(1) 为了防止数据在传输的过程中被破坏,每个信息都包含一个校验码。这个校验码是一个用来保证信息包在传输过程中没有被更改的代码。当信息包到达目的地的时候,接收方会对比校验码和收到的信息中的数据。如果校验码不对,该信息包将被省略。

(2) 为了防止信息包丢失,TCP会要求接收方每收到一个信息包都反馈一下。如果接收方没有提供反馈,发送方会自动重发一次。由于系统会自动处理这个问题,所以程序的开发者根本不用知道问题的出现。TCP会一直试着发送信息包,一直到接收者收到为止,或者它会判断出网络连接断了,并在程序中返回一个错误提示。

(3) 为了防止信息包重复或顺序错误,TCP每传送一个信息包都会传送一个序号。接收方会检查这个序号,确保收到该信息包,并把全部信息包按顺序重新合并。同时,如果接收方看到一个已经看过的序号,则该信息包就会被丢弃。

二、使用客户/服务器模式

在客户/服务器结构下,服务器一直侦听来自客户端的请求,有请求后,就建立连接来处理它们。

客户端总是最开始申请连接的一端,服务器则是等待客户端连接的一端。

1.服务器端端口号

在www.iana.org上有一份由国际因特网地址分配委员会维护的官方已分配的端口列表。

如果编写一个服务器,它的服务不在这个列表,那就应该选一个比1024大,而且在机器上没有被占用的端口号。

这样就避免和其他服务冲突,端口号最大可以为65535。

2.客户端端口号

通常,客户端的端口号不是很重要。一般情况下,客户端会由操作系统随机挑选一个端口号。

客户端的系统会挑选一个保证没有被使用的,被称为“短命”的端口号。

三、理解UDP基础

UDP,它被用来从一个系统向其他的系统传送非常短的消息。

它只提供一个保证:那就是您收到的数据是完整的。

它既不能保证数据是否真的被收到,也不能保证数据是不是只接受一次,还不能保证收到的信息次序是否和发送时候一致。

但是只要没有受到攻击者绕过安全措施后的攻击,通过UDP接收的数据通常都会是完整的。

优点,因为不提供上面那些保证,所以比TCP低级,TCP建立和关闭连接要花费时间,而UDP对连接没有什么概念,所以不存在花费时间建立和关闭连接的问题。(如DNS系统)。

使用参考:

TCP:

# 您需要一个可靠的数据传输,以确保数据完整无缺的到达目的地。

# 您的协议需要不止一个请求和服务器的回答

# 您要发送较多的数据

# 初始连接出现短暂的延迟是可以容忍的

UDP:

# 您不太关心信息包是否到达或者不太在意信息包到达的顺序是否正确,再或者您可以自己察觉这些问题并自己解决

# 您的协议只包括基本请求和回答

# 您需要建立网络会话

# 只传送很少一部分数据.UDP的限制是一个信息包不超过64KB的数据,通常人们只用UDP传送1KB以下的数据

四、底层接口

1.基本客户端操作

import socket,sys

port = 70
host = ‘quux.org‘
filename = ‘/‘

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

try:
  s.connect((host,port))
except socket.gaierror ,e:
  print "Error connecting to server: %s"%e
  sys.exit(1)

s.sendall(filename + ‘\r\n‘)

while 1:
  buf = s.recv(2048)
  if not len(buf):
    break
  sys.stdout.write(buf)

1.1.文件类对象

import socket,sys

port = 70
host = ‘quux.org‘
filename = ‘/‘

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

try:
  s.connect((host,port))
except socket.gaierror ,e:
  print "Error connecting to server: %s"%e
  sys.exit(1)

fd = s.makefile(‘rw‘,0)
fd.write(filename + "\r\n")
for line in fd.readlines():
  sys.stdout.write(line)

通过makefile()函数生成文件类对象,有两个可选参数:操作文件类模式和缓存模式。

操作文件类模式,只读、只写、又读又写。

缓存模式主要用在磁盘文件,但是对于交互式的网络程序,它可能会阻碍程序的运行,所以最好通过设置为0来关上它。

2.基本服务器操作

import socket

host = ‘‘
port = 51423

s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
s.bind((host,port))
s.listen(1)

print "Server is running on port %d; press Ctrl-C to terminate."%port

while 1:
clientsock,clientaddr = s.accept()
clientfile = clientsock.makefile(‘rw‘,0)
clientfile.write("Welcome, " + str(clientaddr) + ‘\n‘)
clientfile.write(‘Please enter a string: ‘)
line = clientfile.readline().strip()
clientfile.write(‘You entered %d characters.\n‘%len(line))
clientfile.close()
clientsock.close()

###### 结果 ######

Welcome, (‘127.0.0.1‘, 62460)
Please enter a string: 123
You entered 3 characters.

遗失对主机的连接。

C:\Users\Administrator>

时间: 2024-11-01 22:55:41

python 网络编程01的相关文章

[python网络编程]DNS服务器

在上一篇中,使用scrapy修改源IP发送请求的最后我们提到由于hosts文件不支持正则,会导致我们的随机域名DNS查询失败.使用DNS代理服务器可以解决这个问题, 下面是我用gevent写的小工具,很简单.我们只拦截匹配的A记录,然后发送DNS Response,如果不匹配,那么我们服务器就是一个DNS代理,转发请求. # -*- coding=utf-8 -*- import struct from cStringIO import StringIO from collections imp

python 网络编程 (二)---tcp

异常 python的socket模块实际上定义了4种可能出现的异常: 1)与一般I/O 和通信问题有关的socket.error; 2)与查询地址信息有关的socket.gaierror; 3)与其他地址错误有关的socket.herror; 4)与在一个socket上调用settimeout()后,处理超时有关的socket.timeout; import socket, sys, time host = sys.argv[1] textport = sys.argv[2] filename

[Python网络编程] DNS缓存解决方案

记得以前写爬虫的时候为了防止dns多次查询,是直接修改/etc/hosts文件的,最近看到一个优美的解决方案,修改后记录如下: import socket _dnscache={} def _setDNSCache(): """ Makes a cached version of socket._getaddrinfo to avoid subsequent DNS requests. """ def _getaddrinfo(*args, **

Python 网络编程

Python 提供了两个级别访问的网络服务.: 低级别的网络服务支持基本的 Socket,它提供了标准的 BSD Sockets API,可以访问底层操作系统Socket接口的全部方法. 高级别的网络服务模块 SocketServer, 它提供了服务器中心类,可以简化网络服务器的开发. 什么是 Socket? Socket又称"套接字",应用程序通常通过"套接字"向网络发出请求或者应答网络请求,使主机间或者一台计算机上的进程间可以通讯. socket()函数 Pyt

[Python网络编程]gevent httpclient以及网页编码

之前看到geventhttpclient这个项目,https://github.com/gwik/geventhttpclient,官方文档说非常快,由于响应使用了C的解析,所以我一直想把这玩意用到项目中, 这两天一直在纠结这玩意,说实在一句话,比较难用,封装的不给力,最大缺陷如下: 1.不支持重定向,重定向需要自己来写,很费事 2.新建的httpclient对象只能发送同域名的请求 这相当的蛋疼,我花了一点时间封装了一下,解决了上面的两个问题,还增加了自动编解码问题,代码如下: #!/usr/

[python] 网络编程之套接字Socket、TCP和UDP通信实例

很早以前研究过C#和C++的网络通信,参考我的文章: C#网络编程之Tcp实现客户端和服务器聊天 C#网络编程之套接字编程基础知识 C#网络编程之使用Socket类Send.Receive方法的同步通讯 Python网络编程也类似.同时最近找工作笔试面试考察Socket套接字.TCP\UDP区别比较多,所以这篇文章主要精简了<Python核心编程(第二版)>第16章内容.内容包括:服务器和客户端架构.套接字Socket.TCP\UDP通信实例和常见笔试考题. 最后希望文章对你有所帮助,如果有不

python 网络编程(五)---DNS域名系统

1.域名系统定义 DNS计算机域名系统由域名服务器和域名解析器组成.通常输入的是网址就是一个域名. 2.域名查询 查询方式包括: 1)正向查询:由域名查找对应的IP(如:119.75.218.77">www.baidu.com->119.75.218.77 ) 2)反向查询:由IP查找域名(如:119.75.218.77 –> www.baidu.com) 查询方式包括: 1)递归查询:当DNS服务器接收到客户端的查询请求时,会做出相应的反应(本地DNS服务器查询.其他服务器查

Python -- 网络编程 -- 抓取网页图片 -- 图虫网

字符串(str)编码成字节码(bytes),字节码解码为字符串 获取当前环境编码:sys.stdin.encoding url编码urllib.parse.quote() url解码urllib.parse.unquote() 列表去重:pages = list(set(pages)) 创建文件夹(可多级创建):os.makedirs(folder)  os.mkdir()只能单级创建 首先分析网页(图虫网)的URL规律: 根网页地址形如: http://tuchong.com/tags/人像/

Python 网络编程(一)

Python 网络编程 socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,应用程序通常通过"套接字"向网络发出请求或者应答网络请求. 百分号的方式相对来说比较老,而format方式则是比较先进的方式,企图替换古老的方式,目前两者. socket和file的区别: file模块是针对某个指定文件进行[打开][读写][关闭] socket模块是针对 服务器端 和 客户端Socket 进行[打开][读写][关闭] socket服务端和客户端的网