无论是p2p还是c/s还是b/s,只要用到通讯,必然是要用到今天写的这个。
python+MYSQL 在pycharm中的使用
TCP/IP是网络软件最核心的部分,缺少这个你只能当做单机游戏玩。
TCP/IP,只需要搞清楚udp和tcp这两个就可以了。
两者的区别在于
udp的保密性不好,所以在做通讯的时候基本选择tcp,这篇文章只提tcp。
先解释一下ip,端口号,套接字都是什么意思:
打个比方: 朋友使用导航去你家找你玩,必然需要知道你住在哪里。
ip就是哪个街道哪个小区哪一撞哪一单元哪一层,端口号是哪一个门。
套接字就是他出发地和目的地,也就是说套接字是两个端点。
import socket
1.使用socket创建套接字:
tcp_client_socket = socket.socket(socket.AF_INET,socekt.SOCK_STREAM)
socket(AF_INET,SOCK_STREAM)
AF_INET决定了要用ipv4地址(32位的)与端口号(16位的)的组合
流式Socket(SOCK_STREAM)是一种面向连接的Socket
2.使用connect()方法连接服务器
tcp_client_socket.connect(("192.168.0.1",8080))
("192.168.0.1",8080)是一个元组,首元素为服务器ip地址,字符型的,8080是服务器当前程序使用端口号,整型的
我的服务器和客户端是在同一个网段的,所以可以直接连接,不同网段需要使用交换机或者网线直连。(校园网wifi会组建内网,即使是同一个路由器也不行,网线直连后修改ip地址就可以了)
3.使用recv()、send()方法收发数据
recv_data = tcp_client_socket.recv(1024) # 客户端接收服务器发来的信息最大长度为1K
data = recv_data.decode("utf-8") #解码
tcp_client_socket.send("123".encode("utf-8)) # 客户端向服务器以utf-8的编码格式发送123
发送字符串的时候需要注意,如果是windows上运行的服务器编码格式是gbk,而linux,mac都是utf-8
4.使用close()方法关闭套接字
tcp_client_socket.close()
1.使用socket创建套接字
tcp_service_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
2.使用bind()绑定本地信息
tcp_service_socket.bind(("",8080))
3.使用listen()加入监听等待客户端接入
tcp_service_socket.listen(128)
4.使用accept()为客户创建新套接字并读取用户ip和端口号
new_client_socket,client_addr = tcp_service_socket.accpet()
这个过程可能不太好理解,大概意思就是你打电话给10086,首先是打给10086的主机,然后主机分配一个话务员给你,帮你办理业务
5.使用recv()/send()发送数据
new_client_socket.send()
recv_data = new.client_socket.recv(1024)
这个和客户端是没有区别的
6.关闭新套接字
new_client_socket.close()
相当于客服业务结束,挂断他所在的分机
7.关闭源套接字
tcp_service_socket.close()
服务器主机ip 192.168.0.1 端口号 8081
客户端主机ip 192.168.0.2 端口由系统分配
客户端源代码
import socket
def main():
# 创建套接字
tcp_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
# 获取服务器的ip port
# addr = ("192.168.0.1",8081)
# 连接服务器
tcp_socket.connect(("192.168.0.1",8081))
# 获取下载文件名
download_file_name = input("文件名")
# 将文件名发送到服务器
tcp_socket.send(download_file_name.encode("utf-8"))
# 接受文件中的数据
recv_data = tcp_socket.recv(1024*1024)
if recv_data:
# 保存接收的数据到文件中
with open("[新]" + download_file_name,"wb") as f:
f.write(recv_data)
# 关闭套接字
tcp_socket.close()
if __name__ == "__main__":
main()
服务器源代码
import socket
def send_file_2_client(new_client_socket,client_addr):
# 接收客户端发送的请求
file_name = new_client_socket.recv(1024).decode("utf-8")
print("客户端(%s)需要下载的文件名为:%s" % (str(client_addr),file_name))
file_content = None
# 打开文件,读取数据
try:
f = open(file_name,"rb")
file_content = f.read()
f.close()
except Exception as ret:
print("没有要下载的文件(%s)" % file_name)
# 发送数据给客户端
if file_content:
# new_client_socket.send("hahahah".encode("utf-8"))
new_client_socket.send(file_content)
def main():
# 创建socket
tcp_server_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
# 绑定本地信息
tcp_server_socket.bind(("",8081))
# 加入监听套接字等待客户端连接
tcp_server_socket.listen(128)
while True:
print("等待一个新客户端的到来")
# 创建新套接字与客户端连接
new_client_socket,client_addr = tcp_server_socket.accept()
print("新客户端已经到来了:%s" % str(client_addr))
# 发送文件
send_file_2_client(new_client_socket,client_addr)
# 关闭套接字
new_client_socket.close()
tcp_server_socket.close()
if __name__ == '__main__':
main()
当然,目前这个只能完成单点操作,加入thread可以实现多任务模式