# 测试&网络编程

### 一、unittest


def one_equation(a,b):
"""
:param a:
:param b:
:return:
ax + b = 0 的解
x = -(b/a)
"""
if a == 0:
raise ValueError("被除数不能为零")
else:
return -(b/a)

def two_equation(a,b,c):
"""
求解一元二次方程a*x*x + b*x + c=0的解
:param a: 方程中二元变量的系数
:param b: 方程中一元变量的系数
:param c: 方程中的常量
:return:  返回方程的根
"""
# (-b + (b**2 - 4ac)**1/2)/2a
# (-b - (b ** 2 - 4ac) ** 1/2)/2a
if a == 0:
raise ValueError("参数错误a!=0")
elif b*b - 4*a*c < 0:
raise ValueError("方程无解")
elif b*b - 4*a*c == 0:
return -b/(2*a)
else:
r1 = (-b + (b*b - 4*a*c)**(1/2))/(2*a)
r2 = (-b - (b*b - 4*a*c)**(1/2))/(2*a)
return r1,r2


"""
.: 测试全通过      .:pass
F: 测试失败        F:fail
E：测试出错        E:error
s: 跳过 该测试     s:skip
"""
class TestFkMath(unittest.TestCase):
def test_one_equation(self):
self.assertEqual(one_equation(5,9),-1.8)
self.assertTrue(one_equation(4,10) == -2.5,.00001)
self.assertTrue(one_equation(4,-27) == 27/4)
# 错的测试用例
self.assertTrue(one_equation(1, -27) == 27/1)
# 求解一元二次方程
def test_two_equation(self):
r1,r2 = two_equation(1,-3,2)
self.assertCountEqual((r1,r2),(1.0,2.0),"求解出错")
r1, r2 = two_equation(2,-7,6)
self.assertCountEqual((r1, r2), (1.5, 2.0), "求解出错")
with self.assertRaises(ValueError):
two_equation(9,4,3)
with self.assertRaises(ValueError):
two_equation(4, 2, 3)

if __name__ == "__main__":
unittest.main()


### 二、TCP/UDP网络编程

#### 2.1 TCP

"""
AF_INET: IPV4协议
AF_INET6: IPV6协议
SOCK_STREAM (TCP链接)
SOCK_DGRAM  (UDP链接)
"""
# tcp ipv4链接
tcp_client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
# bind ip
# 共有65535个端口
# 1000以内都是系统预留的
tcp_client.connect(("127.0.0.1",8005))
# 发送数据到服务器
while True:
data = input("内容: ")
tcp_client.send(data.encode("utf-8"))
data = tcp_client.recv(1024)
print(data.decode("utf-8"))


"""
AF_INET: IPV4协议
AF_INET6: IPV6协议
SOCK_STREAM (TCP链接)
SOCK_DGRAM  (UDP链接)
"""
# tcp ipv4链接
tcp_client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)

# bind ip
# 共有65535个端口
# 1000以内都是系统预留的
tcp_client.connect(("127.0.0.1",8005))
# 发送数据到服务器
while True:
data = input("内容: ")
tcp_client.send(data.encode("utf-8"))
data = tcp_client.recv(1024)
print(data.decode("utf-8"))


​ step1: 先启动服务端

​ step2: 再启动客户端

​ 原则：保证端口一致

#### 2.2 UDP

# 建立UDP
import socket
udp_cli = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
while True:
data = input("请输入你要说的话")
udp_cli.sendto(data.encode("utf-8"),("127.0.0.1",8858))

import socket
udp_serv = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
udp_serv.bind(("127.0.0.1",8858))
while True:


### 三、多线程

# -*- coding:utf-8 -*-
"""
# @project : xcenv
# @Time : 2019/12/21 21:57
# @Author : 摩登老师
# @在线教育机构 : 扣丁学堂
# @个人学习公众号(bilibili) : 猫在大神旁的小C
"""

import socket  # 导入 socket 模块

ADDRESS = ('127.0.0.1', 8712)  # 绑定地址
g_socket_server = None  # 负责监听的socket
g_conn_pool = []  # 连接池

def init():
"""
初始化服务端
"""
global g_socket_server
g_socket_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  # 创建 socket 对象
g_socket_server.listen(5)  # 最大等待数
print("服务端已启动，等待客户端连接...")

def accept_client():
"""
接收新连接
"""
while True:
client, _ = g_socket_server.accept()  # 阻塞 , 等待客户端连接
# 加入连接池
g_conn_pool.append(client)
# 给每个客户端创建一个独立的线程进行管理
# 设置成守护线程

def message_handle(client):
"""
消息处理
"""
client.sendall("连接服务器成功!".encode(encoding='utf8'))
while True:
bytes = client.recv(1024)
print("客户端消息:", bytes.decode(encoding='utf8'))
if len(bytes) == 0:
client.close()
# 删除连接
g_conn_pool.remove(client)
print("有一个客户端下线了。")
break

if __name__ == '__main__':
init()
# 新开一个线程，用于接收新连接
# 主线程逻辑
while True:
cmd = input("""--------------------------

""")
if cmd == '1':
print("--------------------------")
print("当前在线人数：", len(g_conn_pool))
elif cmd == '2':
print("--------------------------")
index, msg = input("请输入“索引,消息”的形式：").split(",")
g_conn_pool[int(index)].sendall(msg.encode(encoding='utf8'))
elif cmd == '3':
exit()


import socket  # 导入 socket 模块

s = socket.socket()  # 创建 socket 对象
s.connect(('127.0.0.1', 8712))
print(s.recv(1024).decode(encoding='utf8'))
s.send("连接了".encode('utf8'))
print(s.recv(1024).decode(encoding='utf8'))
input(" ")