Python打卡学习

Python之网络编程

2018-03-20  本文已影响8人  shenyoujian

一、TCP编程

socket用于打开网络连接,打开一个socket需要知道目标计算机的ip地址和端口号,还有协议类型.大多数的连接都是基于tcp协议连接.tcp连接中,主动发起连接叫客户端,被动响应连接叫服务器.

1、现在我们来创建一个本机与新浪的基于tcp连接的socket
#导入socket库
import socket
#创建一个socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#建立连接
s.connect(('www.sina.com.cn', 80))
#发送数据
s.send(b'GET / HTTP/1.1\r\nHost: www.sina.com.cn\r\nConnection: close\r\n\r\n')
2、创建tcp只需要注意的有三点
3、如果上面都没问题,接下来就可以接收新浪服务器返回的数据了
#接收数据:
buffer = []
while True:
   #每次最多接收1k字节
   d = s.recv(1024)
   if d:
       buffer.append(d)
   else:
       break
print(buffer)            #字节流数组
data = b''.join(buffer) 
with open('data.txt', 'wb') as f:
   f.write(data)        

#关闭数据
s.close()
4、接收数据的点:
5、接收到的数据包括http头和网页本身,我们需要分离它们,我们要的是网页内容
header, html = data.split(b'\r\n\r\n', 1)  #以分隔符是二进制的换行回车,分成n+1个字符串并返回list
print(header)
with open('sina.html', 'wb') as f:
    f.write(html)

# 输出:
# 你可以在python交互式看到一大串字节,里面是新浪的首页和桌面上的data.txt和sina.html,当你打开它们来看
#它们就会自动解码成utf8.
6、那么在新浪服务器那边是怎么知道有客户端连接过来,接受客户端发送的数据和发送给客户端的数据呢?

首先服务器进程要绑定一个端口并且监听来自其他客户端的连接,如果某个客户端连接过来了,服务器就与该客户端建立Socket连接,随后的通信就靠这个Socket连接了。然后每个socket都得依赖4项:服务器地址,服务器端口,客户端地址,客户端端口来唯一确定一个socket.(如果有很多客户端的连接)。最后服务器还要分别响应客户端的请求,所以服务器那边要开启多个进程或者线程来处理,否则服务器一次就只能服务一个客户端.

7、例子:

编写一个简单的服务器程序,它接收客户端连接,把客户端发过来的字符串加上Hello再发回去。
服务端:

import threading,time,socket
#第一步:创建一个基于ipv4和tcp协议的socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#第二步绑定监听的地址和端口.监听的地址可以是0.0.0.0上的所有网络地址,也可以是某个网卡的ip地址上,也可以绑定到本机
#这里我们只有一台电脑所以绑定到本机当绑定到本机的时候,这个服务器就只能接收运行在本机的客户端发来的socket连接.

#监听端口
s.bind(('127.0.0.1', 9999)) #注意传入tuple,小于1024才是标准端口.
s.listen(5) #参数5是指等待连接的最大数量
print('waiting for connection....')

#第三步,服务器程序通过一个永久循环接受来自客户端的连接,accept()会等待并返回一个客户端的连接

# 每个连接都必须创建新线程(或进程)来处理,否则,单线程在处理连接的过程中,无法接受其他客户端的连接
def tcplink(sock, addr):
    print('accept new connection from %s:%s...' % addr)
    sock.send(b'welcome!')
    while True:
        data = sock.recv(1024)
        time.sleep(1)
        if not data or data.decode('utf8')=='exit':
            break
        sock.send(('hello, %s!' % data.decode('utf8')).encode('utf8'))
    sock.close()
    print('connection from %s:%s closed.' % addr)

while True:
    #接受一个新链接:
    sock, addr = s.accept()
    #创建新线程来处理tcp连接:
    t = threading.Thread(target=tcplink, args=(sock, addr))
    t.start()

客户端:

#客户端程序
import socket
#第一步创建一个基于ipv4和tcp协议的socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#第二步建立连接
s.connect(('127.0.0.1',9999))
#第三步先读取服务器传过来的欢迎信息的字节流数据
print(s.recv(1024).decode('utf8'))
#第四步发送数据
for data in [b'Michael', bytes('小明', 'utf8')]:
    s.send(data)
    # 第五步接收数据
    print(s.recv(1024).decode('utf8'))

#最后断开连接
s.send(b'exit')
s.close()


运行截图:


5.png

二、UDP编程

1、udp协议是面向无连接的协议,则你是要udp协议时,是不需要建立连接的,之需要知道对方的ip地址和端口号,但是不一定能到达,但相对tcp速度更快.
2、服务端
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)    #sock_dgram指定了socket类型是udp
#绑定端口:
s.bind(('127.0.0.1', 9999)) 
#不需要调用listen方法
print('bind udp on 9999...')
while True:
    #接收数据:
    data, addr = s.recvfrom(1024) #recvfrom方法返回客户端的数据和地址和端口
    print('received from %s:%s.' %addr) 
    s.sendto(b'hello, %s!' %data, addr) #sendto向客户端发送数据
3、客户端
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
for data in [b'Michael', bytes('小明', 'utf8')]:
    #发送数据
    s.sendto(data, ('127.0.0.1', 9999))
    #接收数据
    print(s.recv(1024).decode('utf8'))  #从服务端接收数据仍然用recv方法
s.close()

三、总结:

1、tcp和udp都是用于网络传输的协议,udp不用建立连接更快但是数据有可能传输不到。
2、tcp服务端的步骤是:

上一篇 下一篇

猜你喜欢

热点阅读