tcp/udp下的socket的基本使用

基于tcp的socket

Tcp是基于链接的,必须先启动服务端,然后启动客户端进行链接

服务端:

ss = socket() #创建服务器套接字
ss.bind() #把地址绑定到套接字
ss.listen() #监听链接
inf_loop: #服务器无限循环
cs = ss.accept() #接受客户端链接
comm_loop: #通讯循环
cs.recv()/cs.send() #对话(接收与发送)
cs.close() #关闭客户端套接字
ss.close() #关闭服务器套接字(可选)

客户端:

cs = socket()    # 创建客户套接字
cs.connect() # 尝试连接服务器
comm_loop: # 通讯循环
cs.send()/cs.recv() # 对话(发送/接收)
cs.close() # 关闭客户套接字

简单的实现:

这里是单个的 一次通信

mport socket           #   AF_INET 基于网络通信, SOCK_STREAM(基于流的,tcp)

phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #   买手机
phone.bind(('127.0.0.1', 8000)) # 绑定手机卡
phone.listen(5) # 开机(监听) # 5表示 最多有5个可以发送连接, 放在链接池中
print('--->')
conn, addr = phone.accept() # (等电话,等待连接,会阻塞)(触发的是3次握手) # 收发消息(在tcp协议中触发的是数据传输)
# 注意收发信息不是用手机, 而是conn这条连接
mesg = conn.recv(1024) # 收消息
print('客户端发来的消息是:',mesg)
conn.send(mesg.upper()) # 发消息 # 断开链接 (在tcp协议中触发的是4次挥手)
conn.close() # 关机
phone.close()

服务端

import socket

phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  # 买手机
phone.connect(('127.0.0.1', 8000)) # 拨通电话 (触发的是三次握手) # 收发数据
# phone.send('hello'.encode('utf-8')) # socket不支持字符串发送,仅支持字节编码发送所以要用
phone.send(bytes('hello', encoding='utf-8')) # 这两个发送一样,只要转换成二进制就行
data = phone.recv(1024)
print('收到服务端发来的消息', data)

客户端

这个是简单的交互模式

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 18-5-14 下午5:56
# @Author : LK
# @File : fu_ceshi.py
# @Software: PyCharm
from socket import *
buffersize = 1024
#
tcp_server = socket(AF_INET, SOCK_STREAM) # 流式套接字
tcp_server.bind(('127.0.0.1', 8000))
tcp_server.listen(5) # 为了接收多个连接
while True:
# 等待连接
conn, add = tcp_server.accept() # 等待连接 ,会阻塞
print('双向连接是:',conn)
print('客户端地址是',add) # 收发信息
while True:
# try:
# 这个异常实在win中,但是在linux下有时候是死循环, 因为客户端突然断掉,conn就没了,mesg一直是空
mesg = conn.recv(buffersize)
if not mesg:
print('客户端你断开连接了')
break
print('服务端接收的信息:',mesg.decode('utf-8'))
conn.send(mesg.upper())
print('服务端以发送回去')
# except Exception:
# break
conn.close()
# 关闭连接 tcp_server.close()

服务端

from socket import *
buffersize=1024
tcp_client = socket(AF_INET, SOCK_STREAM)
# 主动连接
tcp_client.connect(('127.0.0.1', 8000)) # 收发信息
while True:
send_mesg = input('请输入要个服务端发送的信息,break停止').strip('')
# 如果发送的是空格,重新发送
if not send_mesg: continue
if send_mesg == 'break':
print('客户端停止发送信息了')
break
else:
tcp_client.send(send_mesg.encode('utf-8'))
print('客户端已发送消息') mesg = tcp_client.recv(buffersize)
print('客户端接受的信息:',mesg.decode('utf-8')) # 关闭连接
tcp_client.close()

客户端

基于udp的socket

udp是无链接的,先启动哪一端都不会报错

服务端:
ss = socket() #创建一个服务器的套接字
ss.bind() #绑定服务器套接字
inf_loop: #服务器无限循环
cs = ss.recvfrom()/ss.sendto() # 对话(接收与发送)
ss.close() # 关闭服务器套接字 客户端
cs = socket() # 创建客户套接字
comm_loop: # 通讯循环
cs.sendto()/cs.recvfrom() # 对话(发送/接收)
cs.close() # 关闭客户套接字

udp基本实现:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 18-5-15 下午1:38
# @Author : LK
# @File : udp_服务端.py
# @Software: PyCharm from socket import *
ip_port = (('127.0.0.1', 8080))
buffsize = 1024
udp_server = socket(AF_INET, SOCK_DGRAM) # 数据报套接字
udp_server.bind(ip_port)
while True:
data, addr = udp_server.recvfrom(buffsize)
print('客户端发来的消息',data.decode('utf-8'))
udp_server.sendto(data.upper(), addr) # 注意这里是addr
udp_server.close()

udp服务端

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 18-5-15 下午1:38
# @Author : LK
# @File : udp_客户端.py
# @Software: PyCharm
from socket import *
ip_port = (('127.0.0.1', 8080))
buffsize = 1024
udp_client = socket(AF_INET, SOCK_DGRAM) # 数据包套接字 while True:
try:
mesg = input('>>>').strip()
udp_client.sendto(mesg.encode('utf-8'), ip_port)
# recvfrom 接受的是一个元祖, 里面是信息和对方地址
data, addr = udp_client.recvfrom(buffsize)
print('服务端发来的是', data.decode('utf-8'))
# print(data)
except KeyboardInterrupt as e:
print(e)
print('程序异常中断')
break # recv 在自己这端的缓冲区为空时,会阻塞(返回的是信息)
# recvfrom 不会阻塞 (返回是一个元祖,分别是接受的信息和地址) # tcp没有实现并发,而udp默认实现了,因为udp不用建立连接,直接网端口发送,而tcp需要建立连接

udp客户端

udp的客户端可以开多个,

常用函数

服务端套接字函数
s.bind() 绑定(主机,端口号)到套接字
s.listen() 开始TCP监听
s.accept() 被动接受TCP客户的连接,(阻塞式)等待连接的到来 客户端套接字函数
s.connect() 主动初始化TCP服务器连接
s.connect_ex() connect()函数的扩展版本,出错时返回出错码,而不是抛出异常 公共用途的套接字函数
s.recv() 接收TCP数据
s.send() 发送TCP数据(send在待发送数据量大于己端缓存区剩余空间时,数据丢失,不会发完)
s.sendall() 发送完整的TCP数据(本质就是循环调用send,sendall在待发送数据量大于己端缓存区剩余空间时,数据不丢失,循环调用send直到发完)
s.recvfrom() 接收UDP数据
s.sendto() 发送UDP数据
s.getpeername() 连接到当前套接字的远端的地址
s.getsockname() 当前套接字的地址
s.getsockopt() 返回指定套接字的参数
s.setsockopt() 设置指定套接字的参数
s.close() 关闭套接字 面向锁的套接字方法
s.setblocking() 设置套接字的阻塞与非阻塞模式
s.settimeout() 设置阻塞套接字操作的超时时间
s.gettimeout() 得到阻塞套接字操作的超时时间 面向文件的套接字的函数
s.fileno() 套接字的文件描述符
s.makefile() 创建一个与该套接字相关的文件

tcp粘包问题

 

首先要知道socket的收发消息的原理

send 是发送给用 对方后,存在对方的内核态中,

recv 收消息是从自己的缓存中收

只有tcp有粘包现象,udp没有,但是udp会发生丢包问题, 就是发的数据太多,到那时udp的缓冲区,只能接收固定大小,剩下的就丢了, 所以udp没有tcp可靠

流程就是, 服务端发送数据给自己的缓冲区,然后通过网络发送给客户端的缓冲区,
客户端从自己的缓冲区进行取数据,recv函数 一次可能取不完,就可能会出现粘包问题
如果recv取的少的话,或者发送的过多,就可能会出现粘包问题
Recv 是从自己的 内核态中去数据, 如果数据过多的话就会出现粘包问题
解决粘包问题思路: 可以先获取消息的大小, 然后死循环一直发,知道发送到指定大小在停止, 收包也是如此

所谓粘包问题主要还是因为接收方不知道消息之间的界限,不知道一次性提取多少字节的数据所造成的。

粘包的表现

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 18-5-16 上午8:42
# @Author : LK
# @File : tcp_粘包问题_服务端.py
# @Software: PyCharm # 粘包问题发生的原因:
# 第一种情况:tcp在发送的时候,基于流的方式发送数据,发送端要等缓冲区满后才发送出去,造成粘包
# (发送数据的时间很短,数据很小,就会和在一起发送) # 第二种情况,发送端发送的数据很大,但是接收端的缓冲区已经放不下,直接从缓冲区里面拿
# 多次都从缓冲区里面取数据(就是发送的大,但是取的少) # 解决方法:一般是先发送一个数据大小,然后回复一下,在用循环发送数据,高级办法(struct),跟高级(偏函数) from socket import *
tcp_socket = socket(AF_INET, SOCK_STREAM)
ip_port = (('127.0.0.1', 8080))
tcp_socket.bind(ip_port)
tcp_socket.listen(5)
conn, addr = tcp_socket.accept()
print('连接的信息',conn)
print('详细信息',addr)
# 收发数据
while True:
# '''第二种粘包现象,就是发的多,每次收的少'''
# mesg = conn.recv(2)
# print('第一次接受的',mesg.decode('utf-8'))
# mesg = conn.recv(1)
# print('第二次接受的',mesg.decode('utf-8'))
# mesg = conn.recv(1)
# print('第三次接受的',mesg.decode('utf-8')) '''第一种粘包现象, 发的少收得多'''
mesg = conn.recv(1024)
print('第一次接受的',mesg.decode('utf-8'))
mesg = conn.recv(1)
print('第二次接受的',mesg.decode('utf-8'))
mesg = conn.recv(1)
print('第三次接受的',mesg.decode('utf-8')) coon.close()
tcp_socket.close()

粘包的表现_服务端

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 18-5-16 上午8:41
# @Author : LK
# @File : tcp_粘包问题_客户端.py
# @Software: PyCharm from socket import *
tcp_client = socket(AF_INET, SOCK_STREAM)
ip_port = (('127.0.0.1',8080))
tcp_client.connect(ip_port) # 收发消息
while True:
'''第一中粘包现象,发的少,收的多'''
tcp_client.send('第一次发送的'.encode('utf-8'))
tcp_client.send('第二次发送的'.encode('utf-8'))
tcp_client.send('第三次发送的'.encode('utf-8'))
tcp_client.recv(4) # '''第二种粘包现象,发的多收的少'''
# tcp_client.send(b'hhhh')
# tcp_client.send(b'ff')
# tcp_client.recv(4)

粘包的表现_客户端

图解模式:

粘包的本质:接收端不知道,从缓存中取多少

第一种粘包现象:

接收端

发送端

运行结果

第二种粘包现象

接收端

发送端

结果

tcp模拟终端,shell执行结果来显示 粘包问题并解决

如果是linux下 ,不用修改, 输入ls 显示当前目录下的文件,然后输入ifconfig 查看ip等信息,返回的信息比较多,一次不能提取完,再输入其他命令就会产生错误

windows 中 如果产生编码错误就把utf-8 改成gbk

命令用win下的 如 dir  然后 ipconfig 再输入 其他的

#   存在粘包问题

import subprocess
from socket import *
from tcp_模拟终端处理数据 import dealwith ip_port = (('127.0.0.1', 9000))
buffsize = 1024
tcp_server = socket(AF_INET, SOCK_STREAM)
try :
tcp_server.bind(ip_port)
tcp_server.listen(5)
print('还没有人连接')
# 等待多个连接
while True:
try:
conn, addr = tcp_server.accept()
print('客户端连接信息', conn)
print('客户端地址', addr) # 收发消息
while True:
mesg = conn.recv(buffsize)
if not mesg:
print('客户端中断连接了,服务器等待下次连接')
break
print('客户端发送的是', mesg.decode('utf-8')) data = dealwith(mesg)
# 将这些封装成了一个函数
'''
# # 处理从客户端接收的信息
# # res是接收的信息,经过shell脚本处理后的结果
# res = subprocess.Popen(mesg.decode('utf-8'), shell=True,
# stdin=subprocess.PIPE,
# stdout=subprocess.PIPE,
# stderr=subprocess.PIPE
# )
# # 获取错误信息
# err = res.stderr.read().decode('utf-8')
# if not err:
# data = res.stdout.read().decode('utf-8')
# else:
# data = err
''' conn.sendall(data)
print('服务端已发送')
except KeyboardInterrupt as e:
print('外部强制结束')
break conn.close()
except OSError as e:
print('端口以用过') tcp_server.close()

模拟终端_产生粘包_服务端

#   存在粘包问题

from socket import *
tcp_client = socket(AF_INET, SOCK_STREAM)
ip_port = (('127.0.0.1', 9000))
buffsize = 1024
tcp_client.connect(ip_port) while True:
# mesg = input('>>>').strip()
# 去除左右空格
mesg = input('>>>').lstrip().rstrip()
if not mesg: continue
tcp_client.send(mesg.encode('utf8'))
print('客户端已发送')
data = tcp_client.recv(buffsize) if not data:
print('服务端发来的是空信息')
continue
print('服务端发来的信息是:',data.decode('utf-8')) tcp_client.close()

模拟终端_产生粘包_客户端

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 18-5-15 下午5:23
# @Author : LK
# @File : tcp_模拟终端处理数据.py
# @Software: PyCharm
import subprocess
def dealwith(mesg):
# 处理从客户端接收的信息
# res是接收的信息,经过shell脚本处理后的结果
res = subprocess.Popen(mesg.decode('utf-8'), shell=True,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
)
# 获取错误信息
err = res.stderr.read()
if not err:
data = res.stdout.read()
if not data:
# data = '你输入的数据返回值为空'.encode('utf-8')
return '你输入的数据返回值为空'.encode('utf-8')
else:
data = err
return data
# 这里返回的是一个字节的形式 # res = subprocess.Popen('ls', shell=True,
# stdin=subprocess.PIPE,
# stdout=subprocess.PIPE,
# stderr=subprocess.PIPE
# )
# # stdin=subprocess.PIPE, 标准输入, 输入的内容会放在管道中
# # stdout=subprocess.PIPE, 标准输出,就是结果会放在pipe这个管道中
# # stderr=subprocess.PIPE, 标准错误,如果结果错误 会放在这个管道中
#
# # 读取管道内容
# # print(res.stdout.read()), 读取之后,管道里面的就没有输出了

数据处理

第一种处理粘包的方法:

思路: 在发送端首先发送给接受端一个4个字节大小的数据,内容是要发的真是数据的大小.接收端在取数据的时候取4个字节,

然后给发送端发送一个准备接受的信号,当发送端接收到这个信号时,开始发送信息.接收端开始循环接收信息.

struct的用法

import subprocess
from socket import *
from tcp_模拟终端处理数据 import dealwith ip_port = (('127.0.0.1', 9000))
buffsize = 1024
tcp_server = socket(AF_INET, SOCK_STREAM)
try:
tcp_server.setsockopt(SOL_SOCKET, SO_REUSEPORT, 1)
tcp_server.bind(ip_port)
tcp_server.listen(5)
print('还没有人连接')
# 等待多个连接
while True:
try:
conn, addr = tcp_server.accept()
print('客户端连接信息', conn)
print('客户端地址', addr) # 收发消息
while True:
mesg = conn.recv(buffsize)
if not mesg:
print('客户端中断连接了,服务器等待下次连接')
break
print('客户端发送的是', mesg.decode('utf-8')) data = dealwith(mesg)
# 解决粘包:,发送端先发送一个消息的大小,接收端回复一个准备接收的信号,然后发送端开始循环发送信息
length = len(data)
conn.send(str(length).encode('utf-8'))
read_send = conn.recv(buffsize).decode('utf-8') # 注意这里的问题,就是发送一个大的文件,用sendall,,如何发送,还是在于如何取
if read_send == 'read_recv':
conn.sendall(data)
print('服务端已发送') except KeyboardInterrupt as e:
print('外部强制结束')
break conn.close()
except OSError as e:
print('端口以用过')
# tcp_server.close()
tcp_server.close()

解决粘包问题_low版_服务端

  # low版解决粘包问题
from socket import *
import sys tcp_client = socket(AF_INET, SOCK_STREAM)
ip_port = (('127.0.0.1', 9000))
buffsize = 1024 tcp_client.connect(ip_port)
#3 用connect_ex()比较好, 可以重复利用 端口
while True: # 去除左右空格
mesg = input('>>>').lstrip().rstrip()
if not mesg: continue
tcp_client.send(mesg.encode('utf8'))
print('客户端已发送') data_lenth = int(tcp_client.recv(1024).decode('utf-8')) # 解决粘包问题
tcp_client.send('read_recv'.encode('utf-8'))
recv_leng = 0
data = b''
while recv_leng < data_lenth:
if data_lenth - recv_leng > buffsize:
data += tcp_client.recv(buffsize)
recv_leng = len(data)
else:
# 当剩余的数据 小于缓冲区大小时
data += tcp_client.recv(data_lenth - recv_leng)
recv_leng = len(data) if not data:
print('服务端发来的是空信息')
continue
print('服务端发来的信息是:', data.decode('utf-8')) tcp_client.close()

解决粘包问题_low版_客户端

第二种处理粘包方法:推荐使用

思路struct,发送端用struct.pack()  (一般用int类型占4个字节) 将要发送的数据的大小打包后发送过去,然后在发送真实数据.两个必然会粘包.

但是接收端在接收的时候先接收4个字节,然后用struct.unpack()解包,得到数据大小,再利用循环接受真实数据.

struct用法:

http://www.cnblogs.com/coser/archive/2011/12/17/2291160.html
# 用struct 解决粘包
import struct
import subprocess
from socket import *
from tcp_模拟终端处理数据 import dealwith ip_port = (('127.0.0.1', 9000))
buffsize = 1024
tcp_server = socket(AF_INET, SOCK_STREAM)
# 这一句是 重复利用 端口 try:
tcp_server.setsockopt(SOL_SOCKET, SO_REUSEPORT, 1)
tcp_server.bind(ip_port)
tcp_server.listen(5)
print('还没有人连接')
# 等待多个连接
while True:
try:
conn, addr = tcp_server.accept()
print('客户端连接信息', conn)
print('客户端地址', addr) # 收发消息
while True:
mesg = conn.recv(buffsize)
if not mesg:
print('客户端中断连接了,服务器等待下次连接')
break
print('客户端发送的是', mesg.decode('utf-8')) data = dealwith(mesg)
# 解决粘包:,发送端先发送一个消息的大小,接收端回复一个准备接收的信号,然后发送端开始循环发送信息
length = len(data)
conn.send(struct.pack('i', length))
conn.sendall(data)
print('服务端已发送') except KeyboardInterrupt as e:
print('外部强制结束')
break conn.close()
except OSError as e:
print('端口以用过')
# tcp_server.close()
tcp_server.close()

解决粘包-服务端_推荐使用

#   struct解决粘包
from socket import *
import struct
tcp_client = socket(AF_INET, SOCK_STREAM)
ip_port = (('127.0.0.1', 9000))
buffsize = 1024
tcp_client.connect(ip_port) while True:
# mesg = input('>>>').strip()
# 去除左右空格
mesg = input('>>>').lstrip().rstrip()
if not mesg: continue
tcp_client.send(mesg.encode('utf8'))
print('客户端已发送') # 解决粘包
# 服务端会发送过来一个 数据的大小,和 一个真实数据的包,两个必定会粘包,但是解包是分开来解,先解4个字节(对方发来的数据包大小)
data_length = tcp_client.recv(4)
length = struct.unpack('i', data_length)[0] # 循环接收数据
recv_leng = 0
data = b''
while recv_leng < length:
if length - recv_leng > buffsize:
data += tcp_client.recv(buffsize)
recv_leng = len(data)
else:
data += tcp_client.recv(length-recv_leng)
recv_leng = len(data) if not data:
print('服务端发来的是空信息')
continue
print('服务端发来的信息是:', data.decode('utf-8')) tcp_client.close()

解决粘包-客户端

udp 的丢包问题 

#   udp传输数据是以数据报的方式发送,每次发送都是发送完整的数据,但是接收方接收的可能小于发送放,就会产生丢包
# 因为每次都是发送一个完整的,取时也是取完缓冲区,所以不会发生粘包,但是会发生丢包,意味着,这是不安全的
from socket import *
udp_server = socket(AF_INET, SOCK_DGRAM)
ip_port = (('127.0.0.1',8080))
udp_server.bind(ip_port) # 收发消息
while True: # 这里的6 出现两个汉字是因为, 汉字的编码方式不同(3个字节,在win中不同)
data, addr = udp_server.recvfrom(6)
print('第一次接收的信息是:',data.decode('utf-8'))
data, addr = udp_server.recvfrom(6)
print('第二次接收的信息是',data.decode('utf-8'))
# udp_server.sendto(data,addr)

服务端

from socket import  *
udp_client = socket(AF_INET, SOCK_DGRAM)
ip_port = (('127.0.0.1', 8080))
buffsize = 1024 while True:
data = '第一次发送的信息'
udp_client.sendto(data.encode('utf-8'), ip_port)
data = '第二次发送的信息'
udp_client.sendto(data.encode('utf-8'), ip_port)
udp_client.recvfrom(10)

客户端

socket_server实现并发

基于tcp的套接字,关键就是两个循环,一个链接循环,一个通信循环

socketserver模块中分两大类:server类(解决链接问题)和request类(解决通信问题)

#   这样就tcp服务器就能被多个用户链接了, 客户端流程不变
class MyServer(socketserver.BaseRequestHandler):
def handle(self):
# self.request # 相当于 conn
# self.client_address # 相当于 addr
while True:
'''在这里写收发消息''' s = socketserver.ThreadingTCPServer(('127.0.0.1', 8080), MyServer) # 将上面的类实例化一个
s.serve_forever() # 一直开启状态

tcp_socket_server并发版_服务端

import socketserver
import struct
from 封装处理粘包_拆包 import UnPacket, SendData class MyServer(socketserver.BaseRequestHandler):
def handle(self):
self.request
print('连接人的信息')
print('conn是', self.request) # conn
print('addr是', self.client_address) # addr while True:
'''收发消息'''
head_data = self.request.recv(4)
if not head_data: break
real_data = UnPacket(head_data, self.request)
print('客户端发来的是:%s客户端地址是是%s' % (real_data.decode('utf-8'), self.client_address)) # 回复客户端,防止粘包
send_data = 'aaaaaaaa'
SendData(send_data, self.request) if __name__ == '__main__':
# pass
print('还没有人连接')
s = socketserver.ThreadingTCPServer(('127.0.0.1', 8080), MyServer) # 多线程
# s = socketserver.ForkingTCPServer(('127.0.0.1', 8080), MyServer) # 多进程win中不行 # 服务器一直开着
s.serve_forever()

客户端

from socket import  *
from 封装处理粘包_拆包 import UnPacket, SendData
import struct
tcp_server = socket(AF_INET, SOCK_STREAM)
ip_port = ('127.0.0.1', 8080)
buffsize = 1024
tcp_server.connect_ex(ip_port) while True:
'''收发信息'''
mesg = input('>>>').strip()
# 防止粘包处理函数
SendData(mesg, tcp_server)
mesg= tcp_server.recv(4)
if not mesg: break
recv_data = UnPacket(mesg, tcp_server)
print('服务端发送的信息是',recv_data.decode('utf-8'))
tcp_server.close()

处理粘包的问题,封装了一下后是:

封装处理粘包_拆包
import struct
# 传过来包的头部信息,和连接,返回接受的数据是一个byte类型
def UnPacket(head_data ,conn):
buffsize = 4
'''解决粘包,需要传送过数据头,和连接'''
real_data_length = struct.unpack('i',head_data)[0]
real_data = b''
recv_length = 0 # 这个少了点优化
# while recv_length < real_data_length:
# real_data += conn.recv(1024)
# recv_length = len(real_data) while recv_length < real_data_length:
if real_data_length - recv_length > buffsize:
real_data += conn.recv(buffsize)
recv_length = len(real_data)
else:
real_data += conn.recv(real_data_length-recv_length)
recv_length = len(real_data) return real_data # 接受要发送的数据,是字符串,和要发送的链接(客户端发送tcp_server, 服务端发送conn或self.request))
def SendData(real_data,conn):
'''发送包,发两次,'''
head_length = struct.pack('i', len(real_data)) # 后面是一个整数,所以是四个字节, 这里有个优化
conn.send(head_length)
conn.sendall(real_data.encode('utf-8'))
print('客户端发送成功')

python应用之socket编程的更多相关文章

  1. Python 基础之socket编程(二)

    Python 基础之socket编程(二) 昨天只是对socket编程做了简单的介绍,只是把socket通信的框架搭建起来,要对其中的功能进行进一步的扩充,就来看看今天的料哈! 一.基于tcp的套接字 ...

  2. python基础之socket编程 (转自林海峰老师)

    python基础之socket编程   阅读目录 一 客户端/服务器架构 二 osi七层 三 socket层 四 socket是什么 五 套接字发展史及分类 六 套接字工作流程 七 基于TCP的套接字 ...

  3. Python 基础之socket编程(三)

    python 基础之socket编程(三) 前面实现的基于socket通信只能实现什么呢?在tcp协议的通信中就是一个用户说一句,服务端给你回一句,你再给服务端说一句,服务端再给你回一句,就这样一直友 ...

  4. Python 基础之socket编程(一)

    Python 基础之socket编程(一) 可以进行通信玩儿了,感觉不错不错,网络通信就像打电话,我说一句你听一句之后,你再说一句,我听一句,就这样.....下去了.不扯淡了,来来来,看看今天都搞了点 ...

  5. python进阶---Python中的socket编程

    初识socket编程 一.前言 socket基于C\S架构(客户端\服务端)的编程模型,在Python中是以socket模块存在的. Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是 ...

  6. 十三python基础之socket编程

      阅读目录 一 客户端/服务器架构 二 osi七层 三 socket层 四 socket是什么 五 套接字发展史及分类 六 套接字工作流程 七 基于TCP的套接字 八 基于UDP的套接字 九 粘包现 ...

  7. python基础之socket编程

    一 客户端/服务器架构 二 osi七层 三 socket层 四 socket是什么 五 套接字发展史及分类 六 套接字工作流程 七 基于TCP的套接字 八 基于UDP的套接字 九 粘包现象 十 什么是 ...

  8. python编程之socket编程基础

    python socket编程,首先需要import   socket模块 首先创建一个socket对象 expl = socket.socket(socket.AF_INET,socket.SOCK ...

  9. Python之简单Socket编程

    Socket编程这块儿还是比较重要的,记录一下:实现服务器端和客户端通信(客户端发送系统指令,如ipconfig等,服务器端执行该指令,然后将指令返回结果给客户端再传过去,设置一次最多直接收1024字 ...

  10. Python之路【第十篇】: python基础之socket编程

    阅读目录 一 客户端/服务器架构 二 osi七层 三 socket层 四 socket是什么 五 套接字发展史及分类 六 套接字工作流程 七 基于TCP的套接字 八 基于UDP的套接字 九 recv与 ...

随机推荐

  1. <matrix> 73 329

    73. Set Matrix Zeroes - 先扫描第一行第一列,如果有0,则将各自的flag设置为true- 然后扫描除去第一行第一列的整个数组,如果有0,则将对应的第一行和第一列的数字赋0- 再 ...

  2. CF1194F Crossword Expert(数论,组合数学)

    不难的一题.不知道为什么能 $2500$…… 不过场上推错了一直不会优化…… 首先考虑 $f_i$ 表示恰好做完前 $i$ 道题的概率. 这样很难算.修改一下,$f_i$ 表示做完至少 $i$ 道题的 ...

  3. [LeetCode] 854. K-Similar Strings 相似度为K的字符串

    Strings A and B are K-similar (for some non-negative integer K) if we can swap the positions of two ...

  4. 打造个人专属网盘nextcloud

    原文 https://edu.aliyun.com/course/150/lesson/list?spm=5176.9278281.815111.sence.114d4f3eLLMS53

  5. bootstarp treeview 获取勾选和获取Selected选中

    在用treeview的时候,经常会遇到一些官网没有详细说明的东西,比如获取勾选和获取选中的方法,获取选中官网是有明显说明的, 如下 : $('#resourceTree').treeview('get ...

  6. 结合Spring实现策略模式

    最近系统需要对不同维度的数据进行差异化计算,也就会使用不同算法.为了以后更加容易扩展,结合Spring框架及策略模式对实现架构做了系统设计. 1. 定义策略接口(Strategy): import c ...

  7. mysql,字符串类型id,获取最大值

    说明,这个id是字符串类型,但是实际值是一个整数,获取最大值的方法是: select max(cast(id as SIGNED)) from table 另外,mysql生成伪列的方法: SELEC ...

  8. Linux内核定时器struct timer_list

    1.前言 Linux内核中的定时器是一个很常用的功能,某些需要周期性处理的工作都需要用到定时器.在Linux内核中,使用定时器功能比较简单,需要提供定时器的超时时间和超时后需要执行的处理函数. 2.常 ...

  9. 在linux上安装taiga

    # taiga 安装配置 1.简介 本文档介绍了如何部署完整的Taiga服务(每个模块都是Taiga平台的一部分). Taiga平台由三个主要组件组成,每个组件在编译时和运行时都有自己的依赖关系: t ...

  10. 云计算入门(一)、使用vagrant+virtualbox安装虚机

    一.vagrant和virtaulbox简介 Vagrant是一个基于Ruby的工具,用于创建和部署虚拟化开发环境,我们可以使用它来干如下这些事: 建立和删除虚拟机配置虚拟机运行参数管理虚拟机运行状态 ...