进军的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应该是能够一直 ...
随机推荐
- Mock及Mockito使用
mockito http://www.vogella.com/tutorials/Mockito/article.html 原文地址: http://www.open-open.com/lib/vie ...
- intellij idea 相关设置
IDEA这么高端的工具之前只是断断续续使用了一下,因为项目的开发都是在eclipse上,每次学习IDEA的使用都得上网搜索半天,今天自己整理一下,方便以后查阅. IDEA版本15.0.4 字体 界面字 ...
- AND 初识
框架
- 菜鸟教程之学习Shell script笔记(上)
菜鸟教程之学习Shell script笔记 以下内容是,学习菜鸟shell教程整理的笔记 菜鸟教程之shell教程:http://www.runoob.com/linux/linux-shell.ht ...
- java异常——五个关键字(try、catch、finally、throw、throws)
一.try.catch.finally常用组合 try{ xxx }catch(xxxException e){ e.printStackTrace(); } try{ xxx }catch(xxxE ...
- C#对象与XMl文件之间的相互转换(转)
本文是对C#中对象与XMl文件之间的相互转换进行了详细的介绍,需要的朋友可以过来参考下,希望对大家有所帮助 C#提供三种序列化方式,分别为:1.是使用BinaryFormatter进行串行化: 2.使 ...
- php+mysql 原生事务回滚
<?php $conn = mysql_connect('127.0.0.1', 'root', ''); mysql_select_db('msc_test'); mysql_query('S ...
- 面试常问MySQL性能优化问题
知识综述: [1] MySQL中锁的种类: 常见的表锁和行锁,也有Metadata Lock等等,表锁是对一整张表加锁,分为读锁和写锁,因为是锁住整张表,所以会导致并发能力下降,一般是做ddl处理时使 ...
- Scratch 数字游戏
本想用Scratch给女儿做一个类似舒尔特方格的程序来认识数字和提升专注,想想这对刚刚3岁的孩子来说还是比较困难的,于是只做了3*3的方格,来认识数字1-9. 游戏地址:Random 9 v0.21 ...
- Java采用RSA加密及解密技术的有关Maven项目的配置流程:
第一步: 获得RSA公钥私钥(秘钥格式:PKCS#8 ,测试使用的是无私钥密码的) 公钥: -----BEGIN PUBLIC KEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4G ...