进军的socket
在学socket有时候我们会遇到这种问题:

解决方法一:
在服务端中加入:severTCP.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
#!/urs/bin/evn python
# -*- coding:utf-8 -*-
import socket
severTCP = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
severTCP.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
severTCP.bind(("127.0.0.1", 8888)) # 绑定端口
severTCP.listen(5) # 监听
print("starting....")
client, address = severTCP.accept() # 等待连接
while True: # 通信循环
data = client.recv(1024) # 单位:byte. 1024代表最大接收1024个byte,收数据
print("来%s客服端的数据" % client, data.decode("utf-8"))
client.send(data.upper()) # 发数据
client.close()
severTCP.close()
方法二:
发现系统存在大量TIME_WAIT状态的连接,通过调整linux内核参数解决,
vi /etc/sysctl.conf 编辑文件,加入以下内容:
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_fin_timeout = 30 然后执行 /sbin/sysctl -p 让参数生效。 net.ipv4.tcp_syncookies = 1 表示开启SYN Cookies。当出现SYN等待队列溢出时,启用cookies来处理,可防范少量SYN攻击,默认为0,表示关闭; net.ipv4.tcp_tw_reuse = 1 表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭; net.ipv4.tcp_tw_recycle = 1 表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭。 net.ipv4.tcp_fin_timeout 修改系統默认的 TIMEOUT 时间
客户端发送空,卡住,主要是在原因:缓冲区为空,recv就卡住:

服务端:

#!/urs/bin/evn python
# -*- coding:utf-8 -*-
import socket
clientTCP = socket.socket(socket.AF_INET,
socket.SOCK_STREAM)
clientTCP.connect(("127.0.0.1", 8888))
while True:
msg = input(">>:").strip()
if not msg:continue
# if len(msg)==0:continue
clientTCP.send(msg.encode("utf-8"))
data = clientTCP.recv(1024)
print(data.decode("utf-8"))
clientTCP.close()
结果:
客户端

服务端:

当客户端异常断开连接,看见服务端:

Liunx :
#!/urs/bin/evn python
# -*- coding:utf-8 -*-
import socket
severTCP = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
severTCP.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
severTCP.bind(("127.0.0.1", 8888)) # 绑定端口
severTCP.listen(5) # 监听
print("starting....")
client, address = severTCP.accept() # 等待连接
while True: # 通信循环
data = client.recv(1024) # 单位:byte. 1024代表最大接收1024个byte,收数据
if not data: break # 针对Liunx
# if len(data): break
print("来%s客服端的数据" % client, data.decode("utf-8"))
client.send(data.upper()) # 发数据
client.close()
severTCP.close()
windows:
#!/urs/bin/evn python
# -*- coding:utf-8 -*-
import socket
severTCP = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
severTCP.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
severTCP.bind(("127.0.0.1", 8888)) # 绑定端口
severTCP.listen(5) # 监听
print("starting....")
client, address = severTCP.accept() # 等待连接
while True: # 通信循环
try:
data = client.recv(1024) # 单位:byte. 1024代表最大接收1024个byte,收数据
print("来%s客服端的数据" % client, data.decode("utf-8"))
client.send(data.upper()) # 发数据
except ConnectionResetError:
break
client.close()
severTCP.close()
结果:
客户端

服务端:

实现服务端对多个客户端服务(但这没有并发结果)
#!/urs/bin/evn python
# -*- coding:utf-8 -*-
import socket
severTCP = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
severTCP.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
severTCP.bind(("127.0.0.1", 8888)) # 绑定端口
severTCP.listen(5) # 监听
print("starting....")
while True:
client, address = severTCP.accept() # 等待连接
while True: # 通信循环
try:
data = client.recv(1024) # 单位:byte. 1024代表最大接收1024个byte,收数据
if not data:break # Liunx
print("来%s客服端的数据" % client, data.decode("utf-8"))
client.send(data.upper()) # 发数据
except ConnectionResetError:
break
client.close()
severTCP.close()
一个简单聊天功能:
服务端:
#!/urs/bin/env python
# -*- coding:utf-8 -*-
import socket sock_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock_server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock_server.bind(("127.0.0.1", 8888))
sock_server.listen(1) # 开始监听,1代表在允许有一个连接排队,更多的新连接连进来时就会被拒绝
while True:
conn, addr = sock_server.accept() # 阻塞直到有连接为止,有了一个新连接进来后,就会为这个请求生成一个连接对象
print("新人来了", conn.getpeername())
with conn:
print('Connected by', addr)
while True:
try:
data = conn.recv(1024) # 接收1024个字节
print("recv from zq:", conn.getpeername(), data.decode())
if not data: break # 收不到数据,就break response = input(">>>").strip()
conn.send(response.encode("utf-8"))
#print("send to xqx:", response)
except ConnectionResetError:
break
conn.close()
sock_server.close()
客户端:
#!/urs/bin/evn python
# -*- coding:utf-8 -*-
import socket
clientTCP = socket.socket(socket.AF_INET,
socket.SOCK_STREAM)
clientTCP.connect(("127.0.0.1", 8888))
while True:
msg = input(">>:").strip()
if not msg:continue
# if len(msg)==0:continue
clientTCP.send(msg.encode("utf-8"))
data = clientTCP.recv(1024)
print('xqx',data.decode("utf-8"))
clientTCP.close()
结果:
客户端

服务端

文件传输:
#! /urs/bin/evn python
# -*- coding:utf-8 -*-
import socket
import struct
import json
phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # tcp协议
# 链接服务端
phone.connect(("127.0.0.1", 8083))
# 发,收消息
while True:
# 1 发命令
cmd = input(">>>:").strip()
if not cmd:continue
phone.send(cmd.encode("utf-8")) # 发
# 2 以写的方式打开一个新文件,接收服务端发来的文件的内容写入客户端
# 第一步:先收报头长度
obj = phone.recv(4)
header_size = struct.unpack("i", obj)[0]
# 第二步:再收报头
header_bytes = phone.recv(header_size)
# 第三步:从报头中解析出对真实数据的描述信息(数据的长度)
header_json = header_bytes.decode("utf-8")
heade_dic = json.loads(header_json)
print(heade_dic)
total_size = heade_dic["file_size"]
# 第四步:接收真实数据 filename = heade_dic["filename"]
with open(filename, "wb") as f:
recv_size = 0
while recv_size < total_size:
line = phone.recv(1024) # 收。接命令
f.write(line)
recv_size += len(line) # 关闭
phone.close()
#! /urs/bin/evn python
# -*- coding:utf-8 -*-
import socket
import struct
import json
import os
phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # tcp协议
phone.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# 绑定ip和端口
phone.bind(("127.0.0.1", 8083))
# 监听
phone.listen(5)
print("statting....")
# 等待链接
while True: # 链接循环。这里暂时没有并发功能
conn, client_add = phone.accept()
# 这一步对应客服端connect
print(client_add)
while True: # 通信循环
try:
# 1 收命令
res = conn.recv(8192)
# 单位:byte. 1024代表最大接收1024个byte
if not res: break
# 针对异常后(liunx客服端强行停机后,服务端进入死循环,只适用Linux)
# print("客服端的数据", cmd)
# 2 解析命令。提取相应命令参数
cmds = res.decode("utf-8").split()
filename = cmds[1] # 以读的方式打开文件。读取文件内容发送给客服端 # 第一步:制作固定长度的报头
heade_dic = {
"filename": filename,
"md5": "xxxx",
"file_size": os.path.getsize(filename)
}
heade_json = json.dumps(heade_dic)
header_bytes = heade_json.encode("utf-8")
# 第二步:先发送报头的长度
conn.send(struct.pack("i", len(header_bytes)))
# 第三步:再发报头
# print(len(stdout) + len(stderr))
conn.send(header_bytes)
# conn.send(str(total_size).encode("utf-8"))
# 第四步:再发真实的数据
with open(filename, "rb") as f:
for line in f:
conn.send(line)
except ConnectionResetError:
# 适用window操作系统
break
conn.close()
phone.close()
进军的socket的更多相关文章
- python ---socket初识
python网络编程(初识) 一些概念 套接字: 套接字(socket)也叫通信端点,最初用于计算机内部进程之间的通信,而随着网络的发展,套接字被用于计算机之间的通信.举个例子,你(是一台计算机)要打 ...
- socket读写返回值的处理
在调用socket读写函数read(),write()时,都会有返回值.如果没有正确处理返回值,就可能引入一些问题 总结了以下几点 1当read()或者write()函数返回值大于0时,表示实际从缓冲 ...
- Socket聊天程序——Common
写在前面: 上一篇记录了Socket聊天程序的客户端设计,为了记录的完整性,这里还是将Socket聊天的最后一个模块--Common模块记录一下.Common的设计如下: 功能说明: Common模块 ...
- Socket聊天程序——客户端
写在前面: 上周末抽点时间把自己写的一个简单Socket聊天程序的初始设计和服务端细化设计记录了一下,周二终于等来毕业前考的软考证书,然后接下来就是在加班的日子度过了,今天正好周五,打算把客户端的详细 ...
- Socket聊天程序——服务端
写在前面: 昨天在博客记录自己抽空写的一个Socket聊天程序的初始设计,那是这个程序的整体设计,为了完整性,今天把服务端的设计细化记录一下,首页贴出Socket聊天程序的服务端大体设计图,如下图: ...
- Socket聊天程序——初始设计
写在前面: 可能是临近期末了,各种课程设计接踵而来,最近在csdn上看到2个一样问答(问题A,问题B),那就是编写一个基于socket的聊天程序,正好最近刚用socket做了一些事,出于兴趣,自己抽了 ...
- Java中的Socket的用法
Java中的Socket的用法 Java中的Socket分为普通的Socket和NioSocket. 普通Socket的用法 Java中的 ...
- Android Socket连接PC出错问题及解决
最近测试问题:Android 通过Socket链接电脑,ip和端口都是正确的,也在同一网段,可android端就是报异常如下: 解决办法:测试电脑的防火墙可能开着,在控制面板把防火墙打开即可.
- Linux下的C Socket编程 -- server端的继续研究
Linux下的C Socket编程(四) 延长server的生命周期 在前面的一个个例子中,server在处理完一个连接后便会立即结束掉自己,然而这种server并不科学啊,server应该是能够一直 ...
随机推荐
- include和require的区别
include与require除了在处理引入文件的方式不同外,最大的区别就是:include在引入不存文件时产生一个警告且脚本还会继续执行,require则会导致一个致命性错误且脚本停止执行. inc ...
- springboot学习四:整合mybatis
在application.properties加入配置 ## Mybatis 配置 mybatis.typeAliasesPackage=org.spring.springboot.domain my ...
- Django 命令
django #安装: pip3 install django 添加环境变量 #1 创建project django-admin startproject mysite ---mysite ---se ...
- xcode9.4 报错 error:The resource could not be loaded because the App Transport Security policy requires the use of a secure connection.
原因 http | https 协议 不能正常使用 找到的解决方案 但是在字段名上有了变化,不过复制进去 还是会自动选择对应的 解决办法 1. 在Info.plist中添加 App Transpor ...
- Inno setup 操作注册表操作参数详解
原文地址:http://www.dayanzai.me/inno-setup-tut.html [Registry] 段这个可选段用来定义一些你想用安装程序在用户系统中创建.修改或删除的注册表键/值. ...
- Juc中Atomic原子类总结
1 Atomic原子类介绍 2 基本类型原子类 3 数组类型原子类 4 引用类型原子类 5 对象的属性修改类型原子类
- leetcode数据库题目及答案汇总
1. 第二高的薪水 select ifnull((select distinct Salary from Employee order by Salary desc limit 1,1),null) ...
- ArrayList的addAll方法
方法实现如下: public boolean addAll(Collection c) { Object[] a = c.toArray(); int numNew = a.length; ensur ...
- linux下redis的安装方法
一.Linux环境下安装Redis Redis的官方下载网址是:http://redis.io/download (这里下载的是Linux版的Redis源码包) Redis服务器端的默认端口是6 ...
- U3D学习资料收集
1,风宇冲的博客 2,gkEngine 3,@浅墨_毛星云 4,聊聊引擎底层如何实现BRDF渲染算法