Python学习_27
Socket(一)
1、socket简介
socket又称“套接字”,应用程序通常通过“套接字”向网络发出请求或者应答网络请求,使主机或者一台计算机上的进程可以通讯
2、TCP简介
Transmission Control Protocol/Internet Protocol的简写,中译名为传输控制协议/因特网
互联协议,又名网络通讯协议
,是Internet最基本的协议、Internet国际互联网
络的基础,由网络层
的IP协议和传输层
的TCP协议组成。
TCP是面向连接的通信协议,通过三次握手建立连接,通讯完成时要拆除连接,由于TCP是面向连接的所以只能用于端到端的通讯。 TCP提供的是一种可靠的数据流服务,采用“带重传的肯定确认”技术来实现传输的可靠性。
3、UDP简介
UDP协议全称是用户数据报协议
,在网络
中它与TCP
协议一样用于处理数据包,是一种无连接的协议
4、TCP和UDP的区别
TCP可靠性的实现:
a、校验码
b、接收方的反馈
c、信息包附带序号
UDP:
a、快,不需要花费时间建立和关闭连接
b、偶尔丢失一两个消息包无所谓,但是TCP会严格检查
c、UDP的限制是一个信息包不超过64KB
TCP和UDP的区别就是UDP不建立连接,只保证数据的完整性,数据传输快,但是不保证数据是否真的被收到,也不保证数据只够接受一次,也不保证次序;
服务端是用来给一个或者多个客户端提供服务的,当客户端发起请求,开始等待服务端的返回结果,服务端接受完求情以后,根据自己的逻辑进行处理请求,并返回给客户端,客户端接收到返回结果以后,关闭和服务端的连接
5、服务端
a、创建socket
python中用sock()函数来创建套接字,语法格式如下:
socket
.
socket
(address_famili,socket_type
)
参数address_family:
a、socket.AF_INET 默认ipv4
b、socket.AF_INET6 ipv6
c、socket.AF_UNIX 只能用于单一的unix系统间进行通讯
参数socket_type;
a、socket.SOCK_STREAM 流式socket,TCP
b、socket.SOCK_DGRAM 数据包式socket,UDP
TCP的连接写法如下:
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
b、绑定地址端口
用函数bind(address)
address = (
'193.112.92.65'
,
8001
)
s.bind(address)
注意:address
必须是一个元组,IP地址要用引号
c、监听消息
listen(badklog)
listen(badklog),参数badklog是一个数字,代表可以同时接受多少个socket连接
s.listen(
2
)
d、接受连接
这一步,程序需要一个永久循环来接受来自客户端的连接,accept()会等待并返回一个客户端的连接
sock, addr = s.accept()
接受连接并返回元组(conn,addr),其中conn是新的套接字对象,每一个新的连接就创建一个新的对象,可以用来接受和发送数据,addr是客户端的地址,包含host和port
e、发送数据
s.send(string) 发送字符串到连接的套接字,可能未将指定内容全部发送
s.sendall(string) 内部递归调用send,将所有内容发送出去,建议使用。
f、接受数据
data = s.recv(bufsize)
接受套接字数据,数据以字符串形式返回,bufsize指定最多接受的数据量,例如1024,2048
如果不知道接受的数据量有多少,一般通过循环接受
6、客户端
客户端也要首先创建socket套接字
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
客户端连接服务端函数:
s.connect(address) 连接到address的套接字
result = connect_ex(address) 成功返回0,失败返回错误码,推荐使用
7、通用的其他函数
s.close() 关闭socket套接字
s.getsocketname() 获取套接字的名字
s.settimeout(timeout) 设置套接字超时时间,timeout为float类型,单位为秒
s.gettimeout() 获取套接字超时时间
s.setblocking(flag) flage为bool值
setblocking(True) is equivalent to settimeout(None); 相当于不设置超时时间,一直阻塞在那里
setblocking(False) is equivalent to settimeout(0.0). 相当于设置超时时间为0, 如果设置False,那么accept和recv时一旦无数据,则报错
s.fileno() 返回套接字的文件描述符(一个小整数)
8、写一个服务端和客户端,客户端输入一个字符串,服务端收到请求并返回给客户端大写字符串
服务端:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2018\6\1 0001 23:46
# @Author : xiexiaolong
# @File : server.py
import socket
import time
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
address = ('127.0.0.1',8001)
s.bind(address)
s.listen(10)
print("start server!")
while 1:
try:
conn,addr = s.accept()
if conn:
print("recv client from {0}".format(addr))
while 1:
data = conn.recv(2048)
print("recv data:{0}".format(data.decode('utf-8')))
conn.sendall(data.decode('utf-8').upper().encode('utf-8'))
else:
time.sleep(5)
except Exception as e:
conn.close()
客户端:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2018\6\1 0001 23:59
# @Author : xiexiaolong
# @File : client.py
import socket
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
address = ('127.0.0.1',8001)
s.connect(address)
flage = 1
print("start client!")
while flage:
word = input("please input word: ")
if word == "exit":
flage = 0
s.sendall(word.encode('utf-8'))
date = s.recv(2048)
print("recv :{0}".format(date.decode('utf-8')))
s.close()
服务端启动:
D:\python\venv\Scripts\python.exe D:/python/0531/server.py
start server!
recv client from ('127.0.0.1', 53211)
recv data:asds
recv data:fa
客户端收到的结果:
D:\python\venv\Scripts\python.exe D:/python/0531/client.py
start client!
please input word: asds
recv :ASDS
please input word: fa
recv :FA
please input word:
9、课后作业
写一个服务端,写一个客户端,客户端输入linux命令,服务端收到后返回命令执行的结果
服务端
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2018\6\2 0002 0:14
# @Author : xiexiaolong
# @File : server.py
import socket
import os
import sys
import time
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
address = ('127.0.0.1',8001)
s.bind(address)
s.listen(10)
print("server is started!")
while 1:
try:
conn,addr = s.accept()
if conn:
print("recv client from {0}".format(addr))
while 1:
command = conn.recv(2048)
print("recv data:{0}".format(command.decode('utf-8')))
result = os.popen(data.decode('utf-8').read().encode('utf-8'))
data = result.stdout.read()
print(data.decode('utf-8'))
conn.sendall(data.encode('utf-8'))
time.sleep(5)
except Exception as e:
conn.close()
客户端
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2018\6\2 0002 0:30
# @Author : xiexiaolong
# @File : client.py
import socket
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
address = ('127.0.0.1',8001)
s.connect(address)
flage = 1
print("client is started!")
while flage:
command = input("[root@VM_16_3_centos ~]# ")
if command == "exit":
flage = 0
s.sendall(command.encode('utf-8'))
data = s.recv(2048)
print(data.decode('utf-8'))
s.close()
运行结果异常,明天请教老师