day31

第一步骤:

socket服务端

import socket

# 作为服务器必明确自己的ip和端口号 并且不应该变化
# 参数1指定 socket类型AF_INET 表示网络类型
#参数2指定的传输协议为 SOCK_STREAM表示TCP协议 SOCK_DGRAM UDP协议
server = socket.socket(socket.AF_INET,socket.SOCK_STREAM) # 1.买电话机

# 默认就是网络类型 TCP协议
#server = socket.socket()

# 127.0.0.1这叫回送地址 表示当前电脑本身
# ip一定本机ip 本机可能会有多个IP (无线|有限)
# 注意:需要参数是一个元组 端口就是普通整数
server.bind(("127.0.0.1",1688)) # 2.插入手机卡

# 无论是服务器端还是客户端 都是socket 类型

# 开始监听1688端口 盯着这个端口看以后没有数据过来
server.listen() # 3.手机开始待机

# 接收链接请求
# 第一个是表示客户端的socket 第二个客户端的地址信息
client,addr = server.accept() # 4.接电话
# print(type(client))
# print(addr)


# 5.收发数据
data = client.recv(1024)
print(data)
client.send("copy!".encode("utf-8"))

server.close() # 关机

 

 

socket客户端

 

import socket

# 买个电话
client = socket.socket()

# 作为客户端 ip和端口可以变化 所有系统会自动分配随机端给客户端
client.connect(("127.0.0.1",1688))

# 开始通话
# 发送数据 注意发送的内容只能是二进制 bytes
client.send("hello".encode("utf-8"))

# 接收数据 单位为字节
data = client.recv(1024)
print(data)

client.close()

 

#######################################################

第二步骤:windows正常关闭

 

服务端

 

import socket
server = socket.socket()
server.bind(("127.0.0.1",8989))
server.listen()

 

while True:
client_socket,client_addr = server.accept()
buffer_size = 1024 #缓冲区  就是一个临时的容器  
# 缓冲区大小 不能随便写 太大会导致内存溢出 太小效率低 在内存能够承受的情况下 大一些

 

while True:
try:
data = client_socket.recv(1024)
# 在linux中 对方如果强行下线了 服务器不会抛出异常 只会收到空消息
# 得加上判断 如果为空则意味着 对方下线了 应该关闭链接 跳出循环
if not data:
client_socket.close()
break

 

print("收到数据:",data.decode("utf-8")) # 解码时必须保证双方同意编码方式
# 转为大写在发回去
client_socket.send(data.upper())
except ConnectionResetError as e:
print("%s %s" % (client_addr[0],client_addr[1]),e)
# 如果对方下线了 那服务器也应该关闭对应的客户端对象
client_socket.close()
break

 


# 通常服务器不会关闭
# server.close()

 

 客户端

 

 

import socket

 

client = socket.socket()
# 指定服务器的端口和ip 客户端的端口系统自动分配的
client.connect(("127.0.0.1",8989)) #

 


# 添加循环 用来重复收发数据
while True:
# 收发的顺序 必须很对面相反 否则卡死了
msg = input("输入内容:(q:退出)")
if msg == "q":break
if not msg:continue
client.send(msg.encode("utf-8"))
print("sended!")
data = client.recv(1024)
print(data.decode("utf-8"))

 

client.close()

 

 

 

 #############################################

 

 常见的异常


import socket

server = socket.socket()

server.bind(("127.0.0.1",8888)) # 只有服务器需要绑定

server.listen()

# accept 是一个阻塞函数 会一直等到有客户端链接过来 在继续执行
client,addr = server.accept() # 完成了三次握手
# print(client)
# print(addr)

print("握手成功!")
# 收发数据 注意都是用表示客户端的socket来收发数据
# client.send("world".encode("utf-8"))

import time
time.sleep(3)
try:
# data = client.recv(1024)
# print("客户端发来的数据:", data)
# 发送数据时 对方可能也会异常下线 也会抛出异常
# 接收数据 和发送数据都应该放到try
client.send("test".encode("utf-8"))

except:
print("client 下线了")
# 断开链接
client.close() # 完成四次挥手


server.close()
print("服务器关机!")

 

 客户端

 

 

import socket

client = socket.socket()

# connect本质实在进行三次握手 也是一个数据传输的过程 如果服务器没有立马响应 也会阻塞
#
client.connect(("127.0.0.1",8888)) # 三次握手
print("握手成功! client")


# 发送数据 本质上是把数据交给操作系统来进行发送 一旦数据交给了操作系统 后续的发送
# 应用程序就无法控制了 ,send一般不会卡 当然 如果数据量很大就会阻塞
# client.send("hello".encode("utf-8"))
# print("发送完成")

# 是从操作系统缓存区读取数据 如果当前还没有任何数据 就会进入阻塞
# 会一直等到有数据到来 再继续执行
# try:
# data = client.recv(1024)
# print("接收完成!")
# print(data)
# except:
# print("服务器 强行下线了!")


import time
time.sleep(10)
# 客户端执行close 是正常关闭链接 会给服务器送空字节 用于表示要断开链接
client.close()
print("关机了!")

 端口占用的问题

 

 

 

 

import socket
server = socket.socket()

 

server.bind(("127.0.0.1",9891))
server.listen()
server.accept()

 

server.close()

 


# 如果已经开启了服务器 再次运行将会抛出 端口占用异常 把之前开启的服务器关掉即可
"""
有些情况 明明已经关闭了进程 但是 还是端口占用
可能是进程正在后台运行 可以通过端口查出进程 进行关闭
windows下
netstat -ano | findstr 9898
tasklist | findstr 进程id 拿到进程名称
taskkill /f /t /im 进程名称

 

大招: 重启电脑
"""

 

 

 

############################################## 

 

 循环模板

服务器

import socket
server = socket.socket()
server.bind(("127.0.0.1",8989))
server.listen()

while True:
client_socket,client_addr = server.accept()
buffer_size = 1024 #缓冲区  就是一个临时的容器  
# 缓冲区大小 不能随便写 太大会导致内存溢出 太小效率低 在内存能够承受的情况下 大一些

while True:
try:
data = client_socket.recv(1024)
# 在linux中 对方如果强行下线了 服务器不会抛出异常 只会收到空消息
# 得加上判断 如果为空则意味着 对方下线了 应该关闭链接 跳出循环
# windows上正常关闭 也会收到空消息 if 必须要加
if not data:
client_socket.close()
break

print(data.decode("utf-8")) # 解码时必须保证双方同意编码方式
# 转为大写在发回去
client_socket.send(data.upper())
except ConnectionResetError as e:
print("%s %s" % (client_addr[0],client_addr[1]),e)
# 如果对方下线了 那服务器也应该关闭对应的客户端对象
client_socket.close()
break


# 通常服务器不会关闭
# server.close()

 

 

 客户端

 

 

 

import socket

client = socket.socket()
# 指定服务器的端口和ip 客户端的端口系统自动分配的
client.connect(("127.0.0.1",8989)) #


# 添加循环 用来重复收发数据
while True:
# 收发的顺序 必须很对面相反 否则卡死了
msg = input("输入内容:")
if not msg:continue
client.send(msg.encode("utf-8"))
print("sended!")
data = client.recv(1024)
print(data.decode("utf-8"))


client.close()

 

 

 

 

 

 

 

 

posted @ 2019-05-28 21:28  轩辕12  阅读(140)  评论(0编辑  收藏  举报