分享

python网络编程(tcp聊天器)

 yydy1983 2019-08-09

一、基础知识

\qquadtcp,全称传输控制协议,大致的传输过程是服务器向客户端传输数据时,客户端接收到一部分数据后,会对服务器进行反馈,然后服务器再对客户端传输下一部分数据,当服务器超时未收到客户端收到数据的反馈,则会重新发送数据。这就是为什么在下载文件的时候会有一个上传网速,就是因为客户端要反馈收到数据的信息给服务器。
\qquad因此,tcp相对于udp来说,tcp更加稳定,而udp更加简单。现在大多数通信都是用tcp。
\qquadudp相当于寄信,tcp相当于打电话,寄信的时候对方不会告诉你收到与否,真正受到信件后如果对方没有回信,则没有办法确定对方是否收到信息。打电话如果对方收到了则可以听到对方反馈回来的声音,没收到则收到“您拨打的用户暂时无法接听”的反馈,则你可重新打电话过去。

二、编程案例

\qquad 1)编写一个客户端程序,向服务器发送消息或接收服务器的消息。
步骤如下:
\qquada、创建套接字
\qquadb、连接服务器
\qquadc、发送消息/接收消息
\qquadd、关闭套接字

import socket


def main ():
    #创建套接字
    tcp_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    #连接服务器
    server_ip = input("服务器的ip是:")
    server_port = int(input("服务器的port是:"))
    tcp_socket.connect((server_ip,server_port))
    #发送消息
    send_data = input("请输入你要发送的内容:")
    tcp_socket.send(send_data.encode("gbk"))
    #接收消息
    recv_data = tcp_socket.recv(1024)
    print("接收到的信息为:",recv_data.decode("gbk"))
    #关闭套节字
    tcp_socket.close()
    
    
if __name__ == "__main__":
    main()

\qquad 2)编写一个服务器程序,接收客户端的数据并回复消息。步骤如下:
\qquada、创建套接字
\qquadb、bind绑定ip和端口号
\qquadc、lesten使套接字可以被动连接
\qquadd、accept等待客户端连接
\qquade、接收数据,发送数据
\qquadf、关闭套接字

import socket

def main():
	#创建套接字
	tcp_server_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
	#bind绑定ip和端口号
	local_addr = ("",8082)
	tcp_server_socket.bind(local_addr)
	#listen使套接字被动连接
	tcp_server_socket.listen(128)
	#accept等待客户端连接
	client_socket,client_addr = tcp_server_socket.accept()
	#开始循环
	while True:
		#接收数据
		recv_data = client_socket.recv(1024)
		#当客户端断开链接时,recv_data的值为空,则根据此条件设置终止循环条件
		if recv_data:
			print("接收的数据为:",recv_data.decode("gbk"))
		else:
			break
		#发送数据
		client_socket.send("我已收到数据".encode("gbk"))
		#关闭套接字(这里关闭客户端连接服务器时生成的套接字,意味着为这个客户端服务完毕)
	client_socket.close()
	#这里关闭整个服务器生成的套接字,意味着服务器不为任何客户端服务)
	tcp_server_socket.close()

if __name__ == "__main__":
	main()

\qquad 3)写一个文件下载程序
\qquad所谓下载就是服务器的数据发送给客户端,客户端新建一个空文件,接收服务器的数据后,将数据写入空文件中。编写文件下载客户端程序步骤如下:
\qquada、创建套接字
\qquadb、获取服务器的ip和端口号
\qquadc、连接服务器
\qquadd、获取下载文件的名字
\qquade、将文件名字发送给服务器
\qquadf、接收文件中的数据
\qquadg、将数据写入到文件中
\qquadh、关闭套接字

import socket

def main():
	#创建套接字 
	tcp_client_socket = socket(AF_INET,SOCK_ATREAM)
	#获取服务器的ip和端口号
	server_ip = input("请输入服务器的ip:")
	server_port = int(input("请输入服务器的端口号:"))
	#连接服务器 
	tcp_client_socket.connect((server_ip,server_port))
	#获取下载文件的名字 
	download_name = input("请输入需要下载的文件名:")
	#将文件名字发送给服务器 
	tcp_client_socket.send(download_name.encode("utf-8"))
	#接收文件中的数据 (1024指的是接收1k的文件)
	recv_data = tcp_client_socket.recv(1024)
	#将数据写入到文件中 
	with open("[xin]"+download_name,"wb") as f:
		f.write(recv_data)
	#关闭套接字
	tcp_client_socket.close()
	
if __name__ == "__main__":
	main()

\qquad编写文件下载的服务器的程序步骤如下:
\qquada、创建套接字
\qquadb、bind绑定ip和端口号
\qquadc、listen使套接字被动连接
\qquadd、accept等待客户端连接
\qquadf、调用发送文件函数发送文件数据给客户端
\qquad\quadf1) 接收客户端发送过来需要下载的文件名字
\qquad\quadf2) 打开文件,读取数据
\qquad\quadf3) 发送数据给客户端
\qquadg、关闭套接字

import socket

def send_file_data(new_client_socket):
	#接收客户端发送给过来需要下载的文件名字
	file_name = new_client_socket.recv(1024).decode("utf-8")
	#打开文件并读取数据
	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(file_content)

def main():
	#创建套接字
	tcp_server_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
	#bind绑定ip和端口号
	local_addr = ("",8080)
	tcp_server_socket.bind(local_addr)
	#listen使套接字被动连接
	tcp_server_socket.listen(128)
	#accept等待客户端连接
	new_client_socket,new_client_addr = tcp_server_socket.accept()
	while True:
		#调用发送文件数据发送数据给客户端
		send_file_data(new_client_socket)
		new_client_socket.close()
	#关闭套接字
	tcp_server_socket.close()
	
if __name__ == "__main__":
	main()

三、注意事项

\qquad不管是udp,还是tcp,数据发送发可绑定端口号,也可不绑定端口号,数据接收方必须绑定端口号。
\qquad问:我们的电脑可以同时打开两个QQ,显然QQ的端口号不是绑定的,怎么保证可以接收到别人发过来的消息?
\qquad答:A登陆的时候,腾讯服务器就收到A的ip和端口号,B登陆的时候,腾讯服务器同样也收到B的ip和端口号。当A发送消息给B时,消息先发送给腾讯服务器,腾讯服务器收到A的数据,再根据B的ip和端口号将数据转发给B。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多