socket:套接字,在不一样主机之间实现通讯。
udp:用户数据报协议。在通讯开始前不须要创建链接,只须要发送数据便可。不安全
tcp:传输控制协议,面向链接。通讯双方必须先创建链接才能进行数据传输,双方都必须为链接分配系统内核资源,以管理链接状态和传输数据;完成传输后,双方必须断开链接,释放资源。
tcp相似于打电话,udp相似于投递信件。由于链接是1对1的,因此tcp不适用于广播的应用程序,基于广播的应用程序使用udp协议。
单工:只支持数据在一个方向上传输;在同一时间只有一方能接受或发送信息,不能实现双向通讯,举例:电视,广播
半双工:容许数据在两个方向上传输,可是,在某一时刻,只容许数据在一个方向上传输,它其实是一种切换方向的单工通讯;在同一时间只能够有一方接受或发送信息,能够实现双向通讯。举例:对讲机
全双工:容许数据同时在两个方向上传输,所以,全双工通讯是两个单工通讯方式的结合,它要求发送设备和接收设备都有独立的接收和发送能力;在同一时间能够同时接受和发送信息,实现双向通讯,举例:电话通讯
(图片来自网络,若有侵权请联系删除)
在python网络编程中,对于udp协议处理流程以下图:
对于tcp协议的处理流程以下图:html
根据上方流程引出案例:使用udp实现简单的网络通讯python
import socket def send(udp_socket): dest_ip=input("请输入目标ip地址:") dest_port=int(input("请输入目标端口:")) send_date=input("请输入要发送的数据:") udp_socket.sendto(send_date.encode('utf-8'),(dest_ip,dest_port)) #向目标ip:port发送数据 def recv(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) #新建一个ipv4的udp socket udp_socket.bind(("",7788)) #为socket绑定一个端口 while True: print("---------udp聊天----------") print("1:发送消息") print("2:接收消息") print("0:退出系统") op=input("请输入操做编号:") if op == "1": send(udp_socket) elif op == "2": recv(udp_socket) elif op == "0": break else: print("输入错误请从新输入") if __name__=="__main__": main()
同理引出tcp案例:编程
服务端:安全
import socket import threading import time def main(): #tcp_sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM) tcp_service() def tcp_service(): #服务端socket,接收客户端链接,把客户端发来的字符串加上hello发送回去 tcp_sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM) tcp_sock.bind(('127.0.0.1',9999)) tcp_sock.listen(5) #监听端口,传参指定等待链接的最大数量5 print("wait for connect...") while True: sock,addr=tcp_sock.accept() #创建链接 t=threading.Thread(target=tcplink,args=(sock,addr)) #建立一个新线程去处理链接 t.start def tcplink(sock,addr): #为每一个链接创建一个线程 print("Accept new connection from %s:%s" %addr) sock.send(b'Hello') while True: data=sock.recv(1024) time.sleep(1) if not data or data.decode('utf-8') == 'exit': break sock.send(('Hello,%s!' % data.decode('utf-8')).encode('utf-8')) sock.close() print('Connection from %s:%s closed' %addr) if __name__=='__main__': main()
客户端:网络
import socket def main(): test_link() def tcp_client(): #客户端socket,进行数据的发送与收集 tcp_c= socket.socket(socket.AF_INET, socket.SOCK_STREAM) tcp_c.connect(('127.0.0.1',9999)) tcp_c.send(b'GET / HTTP/1.1\r\nHost: www.sina.com.cn\r\nConnection: close\r\n\r\n') # 发送请求 buffer = [] while (True): d = tcp_c.recv(1024) if d: buffer.append(d) else: # 一直接收数据,一次最多接收1024位字节;当接收数据为空时,接收完毕,退出循环 break data = b''.join(buffer) tcp_c.close() header,html=data.split(b'\r\n\r\n',1) #将http头和html分离,http头打印出来,html保存在本地 print(header.decode('utf-8')) with open('test html','wb') as f: f.write(html) def test_link(): #测试链接 tcp_t= socket.socket(socket.AF_INET, socket.SOCK_STREAM) tcp_t.connect(('127.0.0.1',9999)) print(tcp_t.recv(1024).decode('utf-8')) for data in [b'mike',b'bob',b'lili']: tcp_t.send(data) print(tcp_t.recv(1024).decode('utf-8')) tcp_t.send(b'exit') tcp_t.close if __name__=='__main__': main()