tcp客户端
import socket
def main():
tcp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sever_ip = input("请输入服务器的ip:")
sever_port = int(input("请输入服务器的port:"))
sever_addr = (sever_ip, sever_port)
tcp_socket.connect(sever_addr)
send_data = input("请输入要发送的数据:")
tcp_socket.send(send_data.encode('GBK'))
tcp_socket.close()
if __name__ == "__main__":
main()
tcp服务端
import socket
def main():
tcp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcp_socket.bind(("", 7788))
tcp_socket.listen(128)
while True:
new_tcp_socket, socket_addr = tcp_socket.accept()
print(socket_addr)
while True:
recv_data = new_tcp_socket.recv(1024)
print(recv_data.decode('gbk'))
if recv_data:
new_tcp_socket.send("hahhah".encode('gbk'))
else:
break
new_tcp_socket.close()
tcp_socket.close()
if __name__ == "__main__":
main()
文件下载器
import socket
"""
文件下载器客户端
"""
def main():
tcp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ip = input("请输入要连接的服务器的ip:")
port = int(input("请输入要连接的服务器的port:"))
tcp_socket.connect((ip, port))
file_name = input("请输入要下载的文件名")
tcp_socket.send(file_name.encode('utf-8'))
recv_data = tcp_socket.recv(1024)
with open(file_name, 'w', encoding='utf-8') as file:
file.write(str(recv_data.decode('utf-8')))
tcp_socket.close()
if __name__ == "__main__":
main()
import socket
"""
文件下载器服务器端
"""
def main():
tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcp_server_socket.bind(("", 7788))
tcp_server_socket.listen(128)
new_server_socket, socket_addr = tcp_server_socket.accept()
file_name = new_server_socket.recv(1024)
try:
f = open(file_name, 'rb')
file_data = f.read()
f.close()
except:
print("没有要下载的文件")
new_server_socket.send(file_data)
new_server_socket.close()
tcp_server_socket.close()
if __name__ == "__main__":
main()
tcp注意点
- tcp服务器一般情况下都需要绑定, 否则客户端找不到这个服务器
- tcp客户端一般不绑定, 因为是主动链接服务器, 所有只要确定好服务器的ip, port等信息就好, 本地客户端可以随机
- tcp服务器中通过listen可有将socket创建出来的主动套接字变为被动的
- 客户端需要链接服务器时, 就需要使用connect进行链接, udp是不需要链接的而是直接发生, 但是tcp必须先链接, 只有链接成功才能通信
- 当一个tcp客户端连接服务器时, 服务器端会有一个新的套接字, 这个套接字用来标记这个客户端, 单独为这个客户端服务
- listen后的套接字是被动套接字, 用来接收新的客户端的链接请求的, 而accept返回的新套接字是标记这个新客户端的
- 关闭listen后的套接字意味着被动套接字关闭了, 会导致新的客户端不能够链接服务器, 但是之前已经链接成功的客户端正常通信
- 关闭accept返回的套接字意味着这个客户端已经服务完毕
- 当客户端的套接字调用close后, 服务器端会recv解堵塞, 并且返回的长度为0, 因为服务器可以通过返回数据的长度来区别客户端是否已经下线