socket套接字编程
 
套接字介绍
 
1. 套接字 : 实现网络编程进行数据传输的一种技术手段
 
2. Python实现套接字编程:import  socket
 
3. 套接字分类
>流式套接字(SOCK_STREAM): 以字节流方式传输数据,实现tcp网络传输方案。(面向连接--tcp协议--可靠的--流式套接字)
 
>数据报套接字(SOCK_DGRAM):以数据报形式传输数据,实现udp网络传输方案。(无连接--udp协议--不可靠--数据报套接字)

tcp套接字编程
 
服务端流程
 

 from socket import * 

 #创建流式套接字
sockfd = socket(AF_INET,SOCK_STREAM,0) #绑定IP端口
sockfd.bind(('127.0.0.1',8888)) #设置监听套接字,创建监听队列
sockfd.listen(5) while True:
print("waiting for connect....")
#等待客户端链接
connfd,addr = sockfd.accept()
print("connect from",addr) while True:
#收发消息 data = connfd.recv(1024) if not data:
break print(data.decode()) #发消息
connfd.send('来,确认下眼神'.encode())
#关闭套接字
connfd.close() sockfd.close()

TCP_server.py

1. 创建套接字
sockfd=socket.socket(socket_family=AF_INET,socket_type=SOCK_STREAM,proto=0)
功能:创建套接字
参数:  socket_family  网络地址类型 AF_INET表示ipv4
    socket_type  套接字类型 SOCK_STREAM(流式)  SOCK_DGRAM(数据报)
    proto  通常为0  选择子协议
返回值: 套接字对象

2. 绑定地址
>本地地址 : 'localhost' , '127.0.0.1'
>网络地址 : '172.40.91.185'
>自动获取地址: '0.0.0.0'
 

sockfd.bind(addr)
功能: 绑定本机网络地址
参数: 二元元组 (ip,port)  ('0.0.0.0',8888)
```
 
3. 设置监听
sockfd.listen(n)
功能 : 将套接字设置为监听套接字,确定监听队列大小
参数 : 监听队列大小
```
4. 等待处理客户端连接请求
connfd,addr = sockfd.accept()
功能: 阻塞等待处理客户端请求
返回值: connfd  客户端连接套接字
         addr  连接的客户端地址
```
5. 消息收发
data = connfd.recv(buffersize)
功能 : 接受客户端消息
参数 :每次最多接收消息的大小
返回值: 接收到的内容
 
n = connfd.send(data)
功能 : 发送消息
参数 :要发送的内容  bytes格式
返回值: 发送的字节数
```
            
6. 关闭套接字 
sockfd.close()
功能:关闭套接字
```
 客户端流程

 # 接受的客户端

 from socket import * 

 #创建套接字
sockfd = socket(AF_INET,SOCK_STREAM) #发起连接
sockfd.connect(('127.0.0.1',8888)) while True:
msg = input("发消息>> ")
#发送消息
sockfd.send(msg.encode())
if not msg:
break #接收消息
data = sockfd.recv(1024)
print(data.decode()) # msg = input("Msg>>")
# scorfd.send(msg.encode()) # data = sockfd.recv(1024)
# print(data.decode()) #关闭
sockfd.close()

TCP_client.py


           
1. 创建套接字
>注意:只有相同类型的套接字才能进行通信
            
2. 请求连接

sockfd.connect(server_addr)
功能:连接服务器
参数:元组  服务器地址

3. 收发消息
>注意: 防止两端都阻塞,recv send要配合
 
4. 关闭套接字
 
 
tcp 套接字数据传输特点
 
>* tcp连接中当一端退出,另一端如果阻塞在recv,此时recv会立即返回一个空字串。
 
>* tcp连接中如果一端已经不存在,仍然试图通过send发送则会产生BrokenPipeError
 
>* 一个监听套接字可以同时连接多个客户端,也能够重复被连接
 
网络收发缓冲区
 
1. 网络缓冲区有效的协调了消息的收发速度
2. send和recv实际是向缓冲区发送接收消息,当缓冲区不为空recv就不会阻塞。
    
 tcp粘包
 
 socket.time.sleep(0.1)
>原因:tcp以字节流方式传输,没有消息边界。多次发送的消息被一次接收,此时就会形成粘包。
 
>影响:如果每次发送内容是一个独立的含义,需要接收端独立解析此时粘包会有影响。
 
>处理方法
>>1. 人为的添加消息边界
>>2. 控制发送速度
 
 
UDP套接字编程
 
服务端流程
 
 

 from socket import *
import sys
from time import ctime ADDR = ('127.0.0.1',8888)
BUFFERSIZE = 1024 #创建数据报套接字
sockfd = socket(AF_INET,SOCK_DGRAM)
#绑定地址
sockfd.bind(ADDR) #收发消息
while True:
data,addr = sockfd.recvfrom(BUFFERSIZE)
print('recv from %s:%s'%(addr,data.decode()))
sockfd.sendto\
(("[%s] 接收到消息"%ctime()).encode(),addr) sockfd.close() #服务端, udp
from socket import * HOST = '127.0.0.1'
PORT = 9999
ADDR = (HOST, PORT)
#创建数据报套接字
sockfd = socket(AF_INET,SOCK_DGRAM)
#绑定地址
sockfd.bind(ADDR)
#收发消息
while True:
data,addr = sockfd.recvfrom(1024)
print('Receive from %s:%s' % (addr,data.decode()))
# sockfd.sendto(("[%s] 接收到消息"%ctime()).encode(),addr)
sockfd.sendto("收到消息".encode(), addr)
sockfd.close()

UDP_server.py

1. 创建数据报套接字
sockfd = socket(AF_INET,SOCK_DGRAM)
2. 绑定地址 
sockfd.bind(addr)
3. 消息收发        
data,addr = sockfd.recvfrom(buffersize)
功能: 接收UDP消息
参数: 每次最多接收多少字节
返回值: data  接收到的内容
    addr  消息发送方地址
 
n = sockfd.sendto(data,addr)
功能: 发送UDP消息
参数: data  发送的内容 bytes格式
    addr  目标地址
返回值:发送的字节数

4. 关闭套接字
sockfd.close()

客户端流程
 

 from socket import *
import sys #从命令行传入IP和端口
#python3 udp_server.py 172.60.50.42 8888
if len(sys.argv) < 3:
print('''
argv is error!!!
input as
python3 udp_server.py 172.60.50.42 4260
''') HOST = sys.argv[1]
PORT = int(sys.argv[2])
ADDR = (HOST,PORT)
BUFFERSIZE = 1024 #创建数据报套接字
sockfd = socket(AF_INET,SOCK_DGRAM) while True:
data = input("消息>>")
#直接回车退出
if not data:
break
sockfd.sendto(data.encode(),ADDR)
data,addr = sockfd.recvfrom(BUFFERSIZE)
print('从服务器收到:',data.decode())
sockfd.close() #客户端
from socket import *
import sys #命令行输入服务器地址
if len(sys.argv) < 3:
print('''argv is error !!
start as
python3 udp_client.py 127.0.0.1 8888
''')
# raise HOST = sys.argv[1]
PORT = int(sys.argv[2])#字符串转int类型
ADDR = (HOST,PORT) #创建数据报套接字
sockfd = socket(AF_INET, SOCK_DGRAM) while True:
data = input("消息: ")
if not data:
break
sockfd.sendto(data.encode(),ADDR)
data,addr = sockfd.recvfrom(1024)
print("从服务端收到: ", data.decode()) sockfd.close() # $ python3 udp_client.py 127.0.0.1 8888
#要加ip名和端口名才能运行

UDP_client.py

1. 创建套接字
2. 收发消息
3. 关闭套接字
---------------
>总结 :tcp套接字和udp套接字编程区别
>>1. 流式套接字是以字节流方式传输数据,数据报套接字以数据报形式传输
>>2. tcp套接字会有粘包,udp套接字有消息边界不会粘包
>>3. tcp套接字保证消息的完整性,udp套接字则不能
>>4. tcp套接字依赖listen accept建立连接才能收发消息,udp套接字则不需要
>>5. tcp套接字使用send,recv收发消息,udp套接字使用sendto,recvfrom
---------------------

socket套接字属性 
【1】 sockfd.type  套接字类型
 
【2】 sockfd.family 套接字地址类型
 
【3】 sockfd.getsockname() 获取套接字绑定地址
 
【4】 sockfd.fileno() 获取套接字的文件描述符
 
【5】 sockfd.getpeername() 获取连接套接字客户端地址
 
【6】 sockfd.setsockopt(level,option,value)
        功能:设置套接字选项
        参数: level  选项类别   SOL_SOCKET
            option 具体选项内容
            value  选项值
 
【7】 sockfd.getsockopt(level,option)  
        功能 : 获取套接字选项值
 

UDP套接字广播

 #广播接收端   与udp的

 from socket import *

 HOST = ''
PORT = 8880 #创建数据报套接字
s = socket(AF_INET,SOCK_DGRAM)#加默认参数0变成流式套接字SOCK_STREAM
#固定接收端的端口号
s.bind((HOST,PORT))
#设置套接字可以接收广播, 有此后变成与udp不同
s.setsockopt(SOL_SOCKET,SO_BROADCAST,1)#broadcast
#设置套接字保护端口号
s.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)#reuseaddr # while True:
# try:
# message,addr = s.recvfrom(1024)
# print("从{}获取信息{}:".\
# format(addr,message.decode()))#decode将“字节流”按照某种规则转换成'文本' str变unicode
# s.sendto(b"I am here",addr)
# except (KeyboardInterrupt,SyntaxError):#从终端ctrl+c的错
# raise
# except Exception as e:
# print(e) # s.close() while True:
try:
message,addr = s.recvfrom(1024)
print("获取信息: {}".\
format(message.decode()))#decode将“字节流”按照某种规则转换成'文本' str变unicode
s.sendto(b"I am here",addr)
except (KeyboardInterrupt,SyntaxError):#从终端ctrl+c的错
raise#raise 引发一个异常
except Exception as e:#异常类
print(e) s.close()

broadcast_recv.py

 # 发送端

 from socket import *
from time import sleep #发送广播的地址
#<broadcast>
dest = ('176.122.14.255',8880)#端口号9999一致
#创建数据报套接字
s = socket(AF_INET,SOCK_DGRAM)#dgram
#设置能够发送广播
s.setsockopt(SOL_SOCKET,SO_BROADCAST,1)#broadcast while True:
sleep(2)
s.sendto("什么鬼啊aaaaaa啦啦啦啦啦啦啦".encode(),dest)#目标地址
data,addr = s.recvfrom(1024)
print("Received from %s:%s"%(addr,data.decode()))
s.close() # while True:
# data = input('input: ')
# s.sendto(("@鸿182:"+ data).encode(),dest)
# s.close()
# 局域网聊天室,同端口号

broadcast_send.py

* 广播定义 : 一端发送多点接收
     
* 广播地址 : 每个网络的最大地址为发送广播的地址,向该地址发送,则网段内所有主机都能接收。

TCP套接字之HTTP传输
 HTTP协议 (超文本传输协议)
 
1. 用途 : 网页获取,数据的传输
 
2. 特点

应用层协议,传输层使用tcp传输

简单,灵活,很多语言都有HTTP专门接口

无状态,协议不记录传输内容

http1.1 支持持久连接,丰富了请求类型
 
3. 网页请求过程
  1.客户端(浏览器)通过tcp传输,发送http请求给服务端
  2.服务端接收到http请求后进行解析
  3.服务端处理请求内容,组织响应内容
  4.服务端将响应内容以http响应格式发送给浏览器
  5.浏览器接收到响应内容,解析展示

HTTP请求(request)

 """
httpserver v2.0
env: python3.6
io多路复用 和 http训练
""" from socket import *
from select import * # 具体功能实现
class HTTPServer:
def __init__(self, host='0.0.0.0', port=8000, dir=None):
self.host = host
self.port = port
self.dir = dir
self.address = (host, port)
# 多路复用列表
self.rlist = []
self.wlist = []
self.xlist = []
# 实例化对象时直接创建套接字
self.create_socket()
self.bind() # 创建套接字
def create_socket(self):
self.sockfd = socket()
self.sockfd.setsockopt(SOL_SOCKET,
SO_REUSEADDR, 1) # 绑定地址
def bind(self):
self.sockfd.bind(self.address) # 启动服务
def serve_forever(self):
self.sockfd.listen(3)
print("Listen the port %d" % self.port)
# IO多路复用接收客户端请求
self.rlist.append(self.sockfd)
while True:
rs, wx, xs = select(self.rlist,
self.wlist,
self.xlist)
for r in rs:
if r is self.sockfd:
c, addr = r.accept()
self.rlist.append(c)
else:
# 处理请求
self.handle(r) def handle(self, connfd):
# 接收HTTP请求
request = connfd.recv(4096)
# 客户端断开
if not request:
self.rlist.remove(connfd)
connfd.close()
return
# 提取请求内容 (字节串按行分割)
request_line = request.splitlines()[0]
info = request_line.decode().split(' ')[1]
print(connfd.getpeername(), ':', info) # 根据请求内容进行数据整理
# 分为两类 1.请求网页 2.其他
if info == '/' or info[-5:] == '.html':
self.get_html(connfd, info)
else:
self.get_data(connfd, info) # 返回网页
def get_html(self, connfd, info):
if info == '/':
# 请求主页
filename = self.dir + "/index.html"
else:
filename = self.dir + info
try:
fd = open(filename)
except Exception:
# 网页不存在
response = "HTTP/1.1 404 Not Found\r\n"
response += 'Content-Type:text/html\r\n'
response += '\r\n'
response += '<h1>Sorry....</h1>'
else:
# 网页存在
response = "HTTP/1.1 200 OK\r\n"
response += 'Content-Type:text/html\r\n'
response += '\r\n'
response += fd.read()
finally:
# 将响应发送给浏览器
connfd.send(response.encode()) # 其他数据
def get_data(self, connfd, info):
response = "HTTP/1.1 200 OK\r\n"
response += 'Content-Type:text/html\r\n'
response += '\r\n'
response += "<h1>Waiting for httpserver 3.0</h1>"
connfd.send(response.encode()) # 用户使用HTTPServer
if __name__ == "__main__":
"""
通过 HTTPServer类快速搭建服务,展示自己的网页
"""
# 用户决定的参数
HOST = '0.0.0.0'
PORT = 8000
DIR = './static' # 网页存储位置 httpd = HTTPServer(HOST, PORT, DIR) # 实例化对象
httpd.serve_forever() # 启动服务

HTTP_server.py

 #静态网页处理器
#采用循环的模式,无法满足客户端长连接 from socket import *#网络连接端点,导入模块 #处理客户端请求, 交互
def handleClient(connfd):#请求,调用函数
request = connfd.recv(2048)#请求套接字接受文件
# print('**************')
# print(request)
# print('**************')
#按照行切割请求, 方便查看
request_lines = request.splitlines()
for line in request_lines:
print(line.decode())#对分割后的文件解码 try:
f = open("index.html")
except IOError:#找不到页面, 文件出错
response = "HTTP/1.1 303 not Found\r\n"#http响应行
response += '\r\n'#无响应头, 有空行
response += '''====sorry ,file not find
*******************************
Sorry bing i love you miss you.
*******************************
'''
else:#正常情况运行
response = "HTTP/1.1 200 OK\r\n"#成功响应头, 响应体是页面
response += '\r\n'
response += f.read()#响应体是页面
# for i in f:
# response += i
finally:
connfd.send(response.encode())#发送给浏览器
connfd.close() #流程控制
def main():
sockfd = socket()#创建流式套接字
sockfd.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)#设置端口重用
sockfd.bind(('0.0.0.0',8888))#绑定套接字
sockfd.listen(10)#监听套接字
while True:#循环监听等待连接
print("Listen the port 8000..")
connfd,addr = sockfd.accept()#创建另一个套接字连接请求,便于接收一个后再接收,
#处理浏览器发来的请求
handleClient(connfd)#跟客户顿交互
connfd.close()#关闭套接字 if __name__ == "__main__":#调用主函数
main() # --------------------------------------------------------------- # #接收请求
# #查看请求
# #返回客户端请求 # def handleClient():
# pass # #创建tcp套接字, 调用handleClient完成功能
# def main():
# pass # if __name__=="__main__":
# main()

HTTP_server.py

 <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>欢迎进入Alan主页</title>
</head>
<body>
<h1>Alan songzihong welcome to you </h1>
<h1>what is you name</h1>
<h1>How can i do cna help you </h1>
</body>
</html> <!-- 没保存会只显示文件名 -->
<!-- html:5 + tab -->
<!-- h1 + tab -->

index.html

* 请求行 : 具体的请求类别和请求内容
 
```
    GET         /        HTTP/1.1
    请求类别   请求内容     协议版本
```
 
请求类别:每个请求类别表示要做不同的事情  
 
```        
        GET : 获取网络资源
        POST :提交一定的信息,得到反馈
        HEAD : 只获取网络资源的响应头
        PUT : 更新服务器资源
        DELETE : 删除服务器资源
        CONNECT
        TRACE : 测试
        OPTIONS : 获取服务器性能信息
```
 
* 请求头:对请求的进一步解释和描述
```
Accept-Encoding: gzip
```
* 空行
* 请求体: 请求参数或者提交内容

http响应(response)
 
1. 响应格式:响应行,响应头,空行,响应体
 
* 响应行 : 反馈基本的响应情况
 
```         
HTTP/1.1     200       OK
版本信息    响应码   附加信息
```
 
响应码 :  
```
1xx  提示信息,表示请求被接收
2xx  响应成功
3xx  响应需要进一步操作,重定向
4xx  客户端错误
5xx  服务器错误
```
* 响应头:对响应内容的描述
```             
Content-Type: text/html
```
 
* 响应体:响应的主体内容信息

socket套接字编程 HTTP协议的更多相关文章

  1. linux网络环境下socket套接字编程(UDP文件传输)

    今天我们来介绍一下在linux网络环境下使用socket套接字实现两个进程下文件的上传,下载,和退出操作! 在socket套接字编程中,我们当然可以基于TCP的传输协议来进行传输,但是在文件的传输中, ...

  2. linux网络编程-(socket套接字编程UDP传输)

    今天我们来介绍一下在linux网络环境下使用socket套接字实现两个进程下文件的上传,下载,和退出操作! 在socket套接字编程中,我们当然可以基于TCP的传输协议来进行传输,但是在文件的传输中, ...

  3. socket 套接字编程

    今日内容 socket 套接字编程 简易服务端与客户端代码实现 通信循环 黏包现象(TCP协议) 报头制作.struct 模块.封装形式 内容详细 一.socket 套接字编程 实现一款能够进行数据交 ...

  4. 基于TCP协议的socket套接字编程

    目录 一.什么是Scoket 二.套接字发展史及分类 2.1 基于文件类型的套接字家族 2.2 基于网络类型的套接字家族 三.套接字工作流程 3.1 服务端套接字函数 3.2 客户端套接字函数 3.3 ...

  5. Linux之socket套接字编程20160704

    介绍套接字之前,我们先看一下传输层的协议TCP与UDP: TCP协议与UDP协议的区别 首先咱们弄清楚,TCP协议和UCP协议与TCP/IP协议的联系,很多人犯糊涂了,一直都是说TCP/IP协议与UD ...

  6. 基于TCP连接的socket套接字编程

    基于TCP协议的套接字编程(简单) 服务端 import socket server = socket.socket() server.bind( ('127.0.0.1', 9999) ) serv ...

  7. day31 socket套接字编程

    为什么要有套接字编程? 在上节课的学习中,我们学习了OSI七层协议,但是如果每次进行编程时我们都需要一层一层的将各种协议使用在我们的程序中,这样编写程序实在是太麻烦了,所以为了让程序的编写更加的简单, ...

  8. socket套接字编程(1)——基本函数

    TCP交互流程: 服务器:1. 创建socket:2. 绑定socket和端口号:3. 监听端口号:4. 接收来自客户端的连接请求:5. 从socket中读取字符:6. 关闭socket. 客户端:1 ...

  9. 19、网络编程 (Socket套接字编程)

    网络模型 *A:网络模型 TCP/IP协议中的四层分别是应用层.传输层.网络层和链路层,每层分别负责不同的通信功能,接下来针对这四层进行详细地讲解. 链路层:链路层是用于定义物理传输通道,通常是对某些 ...

随机推荐

  1. 【LeetCode+51nod】股票低买高卖N题

    [121]Best Time to Buy and Sell Stock (2018年11月25日重新复习) 给一个数组代表股票每天的价格,只能有一次交易,即一次买入一次卖出,求最大收益. 题解:用一 ...

  2. 无法用另一台电脑上的navicat链接主机数据库lost connection toMYSQl server at "handshake":reading inital communication packet,system error:34

    同事要用navicat登陆我的数据库,主机地址和密码都没错,但是报错,lost connection toMYSQl server at "handshake":reading i ...

  3. DevOps打造端到端的价值交付

    首先就要来说下什么是端到端: 敏捷帮助我们解决了开发域从计划到测试(部分测试内容)的问题 持续集成帮助解决了从计划到测试完成的过程 持续发布解决了从计划到待发布的过程 持续部署解决了从计划到已上线的过 ...

  4. sql查询时间范围

    select * from table where Time>='2019-05-09 00:05:36' and Time<='2019-05-10 00:05:36'

  5. u-tools图床便捷生成markdown图片

    u-tools 图床 上传图片生成markdown图片非常便捷. 支持的图片服务器有几种,其中搜狗.网易和掘金的加载速度更快些: 也可以用阿里与和腾讯云的OSS; 其中网易生成图片不是原图尺寸好像被改 ...

  6. jmeter+ant+jenkins搭建接口自动化测试环境

    jmeter+ant+jenkins搭建接口自动化测试环境(基于win) 1.jmeter jmeter依赖java运行环境,所以需要提前下载jdk并配置好环境变量 官网下载(http://jmete ...

  7. wamp环境的搭建

    本文详细介绍了在Windows2003下使用Apache2.2.21/PHP5.3.5/Mysql5.5.19/phpMyAdmin3.4.9搭建php开发环境. 第一步:下载安装的文件 1. Apa ...

  8. STM32输入捕获TIM2四通道

    相比于一通道,原子的例程里因为清了计数时间,所以要对程序进行修改. 记录上升沿后的计数,然后记录下降沿的计数.相减后计算高电平时间,对于定时器中断间隔的边界要分开处理. 这里因为我的接收机时间是1ms ...

  9. k-近邻算法(kNN)准备数据:归一化数值

    #准备数据:归一化数值 def autoNorm(dataSet): #autoNorm()函数可以自动将数字特征值转换为0到1的区间 minVals = dataSet.min(0) maxVals ...

  10. webbrowser控件显示word文档

    参照某网站上的步骤(http://www.kuqin.com/office/20070909/968.html)首先,在Visual Studio中创建一个C#语言的Windows应用程序,然后在左侧 ...