Socket网络编程

网络

为了把全世界不同类型的计算机都连接起来,规定了一套全球通用的协议,即互联网协议簇(Internet Protocol Suite),从而实现资源共享和通信的目的。

TCP/IP简介

1.IP协议
是32位的整数,简称IPv4

2.TCP协议
传输层协议,负责在两台计算机之间建立可靠连接,保证数据包按顺序到达。
通过3次握手建立可靠连接之后对每个IP包进行编号,确保对方按顺序收到,如果包丢了就重发。
这个协议包含端口,服务即一个程序是通过端口来区分的,1-1023端口归系统使用,程序使用端口从1024-65535。
主要用于文件传输等

3.UDP协议
传输层协议,面向无连接,即不需要建立连接,只需要对方的IP地址跟端口号即可直接发送数据包。
比TCP协议更快。
广泛用于语音广播,视频电话等。

4.TCP/IP四层结构
应用程
传输层
网络层
链路层

Socket套接字

socket含义为插座,作用是提供给程序可以对外进行连接的模块。

语法

tcpSock = socket.socket(AddressFamily, Type)
'''
Address Family:AF_INET用于Internet通信(常用),AF_UNIX用于同一台机器进程间通信。
Type:套接字类型,SOCK_STREAM表示使用TCP协议,SOCK_DGRAM表示使用UDP协议
'''

socket常用方法
参考菜鸟教程

TCP编程

步骤

  1. 使用socket()创建一个套接字
  2. 使用bind()绑定IP和Port
  3. 使用listen()开启TCP监听,设置最大连接数量
  4. 使用accept()被动接受客户端连接
  5. 使用recv/send()接发数据

案例

#使用服务器向客户端浏览器发送Hello World
import socket

host = ''
port = 8080
web = socket.socket()#变量web就是一个socket对象
web.bind((host,port)) #这里的参数是元组
web.listen(5)
print('服务器开始等待客户端连接...')
#为了一直等待需要使用死循环
while True:
    conn,addr = web.accept() #将结果赋值给元组,conn为新的socket连接对象,addr是连接客户端的ip地址跟端口号是一个元组
    data = conn.recv(1024) #指定接受1024个字节
    print(addr)
    #向客户端发送数据,b表示字节数据,返回头跟内容需要有两个空格,使用\r\n表示,windows系统\r\n表示空格,linux系统\r表示空格
    conn.sendall(b'HTTP/1.1 200 OK\r\n\r\nHello World')
    conn.close()
'''
out:
服务器开始等待客户端连接...
b'GET / HTTP/1.1\r\nHost: 127.0.0.1:8080\r\nUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:83.0) Gecko/20100101 Firefox/83.0\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8\r\nAccept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2\r\nAccept-Encoding: gzip, deflate\r\nConnection: keep-alive\r\nUpgrade-Insecure-Requests: 1\r\nCache-Control: max-age=0\r\n\r\n'
'''

创建TCP客户端

客户端代码如下

import socket

host = '127.0.0.1'
port = 8080
client = socket.socket()
client.connect((host,port))
send_data = input('请输入要发送的数据:')
#需要将字符串转换为byte
client.send(send_data.encode())
#接收服务器返回的内容,同时设置接受的最大字节为1024,因为接收到的数据是byte还需要转换为字符串
recv_data = client.recv(1024).decode()
print('接收到的数据是:',recv_data)
client.close()
'''
out:
请输入要发送的数据:213123
接收到的数据是: HTTP/1.1 200 OK

Hello World
'''

制作简易聊天窗口

对讲机式聊天,你说一句,我说一句,不能同时说话。

服务器端代码,注意服务端代码需要先运行。

import socket

host = socket.gethostname()
port = 22222
#参数含义依次为 使用IPV4,TCP
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.bind((host,port))
#因为是1对1,所以监听数量设置为1
s.listen(1)
#会收到sock对象,addr元组,里面包括服务器的ip地址跟端口
sock,addr = s.accept()
print('连接已经建立!')
info = sock.recv(1024).decode()
while info != 'bye':
    if info:
        print('对方说:',info)
    send_data = input('你说:')
    sock.send(send_data.encode())
    if send_data == 'bye':
        break
    info = sock.recv(1024).decode()
sock.close()
s.close()

客户端代码

import socket

host = socket.gethostname()
port = 22222
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect((host,port))
print('已经连接!')

info = ''
while info != 'bye':
    send_data = input('你说:')
    s.send(send_data.encode())
    if send_data == 'bye':
        break
    info = s.recv(1024).decode()
    print('对方说:',info)
s.close()

udp编程

直接说案例吧。

将摄氏温度转换为华氏温度案例

#服务器端脚本
import socket

#参数说明依次为 IPv4,使用UDP协议
s = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
s.bind(('127.0.0.1',8888))
print('服务器已启动!')
#接受数据
data , addr = s.recvfrom(1024)
data = float(data)*1.8 +32
send_data = '转化后的华氏温度:'+str(data)
#addr是一个元组,第一个值是IP地址,第二个值是元组
print('Recieved from %s:%s' %addr)
s.sendto(send_data.encode(),addr)
s.close()

客户端脚本

#UDP客户端
import socket

s = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
data = input('请输入摄氏温度:')
s.sendto(data.encode(),('127.0.0.1',8888))
print(s.recv(1024).decode())
s.close()

学习来自:《python从入门到项目实践》明日科技 第十七章
posted @ 2020-12-06 23:58  努力吧阿团  阅读(187)  评论(0编辑  收藏  举报