使用工具:
Ubuntu:vim
Ubuntu:Python 3.7
网络调试助手 netassist 3.7(windows版本)
前言:网络编程实现计算机之间的通信,通过 指定的协议实现数据的发送与接收,从而达到计算机之间的通信。
TCP/UDP协议,计算机实现通信要遵守的规则:
UDP协议简单但是不稳定,容易出现丢包的情况,而TCP相比UDP而言,比较复杂,稳定且数据不容易丢失。
以下代码在Python3.7环境实现。
UDP的使用:
使用UDP向指定网络位置发送数据:
import socket #导入包
def main():#定义函数
#1.创建一个套接字
udp_socket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
#2向指定网络位置发送数据(b表示将数据转换为二进制,("192.168.188.1",8000)是个元组,表示数据的目的地IP及port)
udp_socket.sendto(b"haahahah",("192.168.188.1",8000))
#3关闭套接字
udp_socket.close()
#需要特别注意主函数的写法
if __name__=="__main__":
main()
手动输入即将发送的消息:
import socket
def main():
udp_socket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
contents=input("input message")
#将需要发送的数据进行编码处理
udp_socket.sendto(contents.encode("UTF-8"),("192.168.188.1",8000))
udp_socket.close()
if __name__=="__main__":
main()
实现循环发送消息:
import socket
def main():
#可以使用Ctrl+c强制结束
while True:
udp_socket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
contents=input("input message")
udp_socket.sendto(contents.encode("UTF-8"),("192.168.188.1",8000))
udp_socket.close()
if __name__=="__main__":
main()
带有退出的循环发送:
import socket
def main():
while True:
udp_socket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
contents=input("input message")
#输入exit触发if条件退出循环
if contents == "exit":
break
udp_socket.sendto(contents.encode("UTF-8"),("192.168.188.1",8000))
udp_socket.close()
if __name__=="__main__":
main()
接收信息:
import socket
def main():
udp_socket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
#定义一个地址元组
localaddr = ('',2000)
#作为服务器一端绑定自己 的位置
udp_socket.bind(localaddr)
#使用套接字进行数据的接收,1024表示接收数据的大小
recv_date=udp_socket.recvfrom(1024)
#打印接受到的数据
print(recv_date)
udp_socket.close()
if __name__== "__main__":
main()
实现一个简单聊天室的案例:
import socket
def send_msg(udp_socket):
dest_ip = input("ip:")
dest_port = int(input("port:"))
msg = input("msg:")
udp_socket.sendto(msg.encode("utf-8"),(dest_ip,dest_port))
def recv_msg(udp_socket):
recv_data = udp_socket.recvfrom(1024)
#标准格式输出
print("%s:%s" %(str(recv_data[1]),recv_data[0].decode("utf-8")))
def main():
udp_socket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
udp_socket.bind(("",5000))
while True:
#选项操作
print("___choose___")
print("1 to send")
print("2 to resv")
print("3 to exit")
op = input("please input:")
if op == "1":
send_msg(udp_socket)
elif op == "2":
recv_msg(udp_socket)
elif op == "3":
break
else:
print("error!")
if __name__=="__main__":
main()
TCP的使用:
向指定服务器发送数据
import socket
def main():
#创建套接字
tcp_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
#输入服务器ip地址及port
server_ip = input("server IP:")
server_port =int( input("server port:"))
#连接指定服务器
tcp_socket.connect((server_ip,server_port))
#输入即将发送的消息
msg = input("msg:")
#对发送的 消息进行编码处理
tcp_socket.send(msg.encode("gbk"))
#关闭套接字
tcp_socket.close
if __name__=="__main__":
main()
TCP的服务器
import socket
def main():
tcp_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
address = ("",5000)
#服务绑定一个ip及port
tcp_socket.bind(address)
#将套接字变为被动状态(监听)
tcp_socket.listen(128)
while True:
print("waiting....")
#拆包得到一个新的套接字及一个客户端的地址
new_socket, new_addr = tcp_socket.accept()
print("new client%s" %str(new_addr))
while True:
new_msg = new_socket.recv("1024")
#对接收到的信息进行解码输出
print("msg%s" %new_msg.decode("utf-8"))
if new_msg:
#服务器回送消息进行编码
new_msg.send("hahah...".encode("utf-8"))
else:
break
new_socket.close()
print("over...")
tcp_socket.close()
if __name__=="__main__":
main()
使用TCP下载文件:
客户端发送请求及接收数据简单版
import socket
def main():
tcp_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
dest_ip = input("input_server_ip:")
dest_port = int(input("input_server_port:"))
#连接到服务器
tcp_socket.connect((dest_ip,dest_port))
download_file_name = input("input file name:")
#向服务器发送下载文件的请求
tcp_socket.send(download_file_name.encode("utf-8"))
#接收服务器发送过来的数据
recv_data = tcp_socket.recv(1024)
if recv_data:
with open("[new]"+download_file_name,"wb") as f:
f.write(recv_data)
tcp_socket.close()
if __name__=="__main__":
main()
服务器端的代码:
import socket
def send_2_client(new_socket,new_addr):
file_name = new_socket.recv(1024).decode("utf-8")
#the client want to download the file(客户端请求下载的文件名称)
print("the client(%s) want to download the file which name is %s" %(str(new_addr),file_name))
#将读出文件内容置为空
file_content = None
#加上异常处理语句,防止文件打不开出现异常
try:
#rb表示读文件用二进制读出并发送,这时要注意异常处理,wb可以使用with用法,不用考虑文件打不开的情况
f = open(file_name,"rb")
#读文件到file_content
file_content = f.read()
f.close()
except Exception as ret:
print("there is no file which name is %s" % file_name)
#如果文件读出内容则执行发送命令
if file_content:
new_socket.send(file_content)
def main():
tcp_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
tcp_socket.bind(("",7788))
tcp_socket.listen(128)
while True:
new_socket,new_addr = tcp_socket.accept()
#调用函数
send_2_client(new_socket,new_addr)
new_socket.close()
tcp_socket.close()
if __name__=="__main__":
main()
with打开文件的用法:
with open("[new]"+download_file_name,"wb") as f:
f.write(recv_data)
使用with打开文件时会自动调用close函数关闭文件