网络通信 使用网络的目的
把多方链接在一起,进行数据传递;
网络编程就是,让不同电脑上的软件进行数据传递,即进程间通信;
IP地址是什么:比如192.168.1.1 这样的一些数字;
ip地址的作用:用来在电脑中 标识唯一一台电脑,比如192.168.1.1;在本地局域网是唯一的。
查看网卡信息
Linux:ifconfig
windows:ipconfig
ensxx:用来与外部进行通信的网卡;
lo:环回网卡,用来进行本地通信的;
linux关闭/开启网卡:sudo ifconfig ensxx down/up
ip和ip地址的分类ip分为ipv4和ipv6
ip地址分为:
A类地址
B类地址
C类地址
D类地址--用于多播
E类地址--保留地址,因ipv6诞生,已无用
私有ip
单播--一对一
多播--一对多
广播--多对多
ip:标识电脑;
端口:标识电脑上的进程(正在运行的程序);
ip和端口一起使用,唯一标识主机中的应用程序,进行统一软件的通信;
知名端口
固定分配给特定进程的端口号,其他进程一般无法使用这个端口号;
小于1024的,大部分都是知名端口;
范围从0~1023;
动态端口
不固定分配,动态分配,使用后释放的端口号;
范围1024~65535;
socket是进程间通信的一种方式,能实现不同主机间的进程间通信,即socket是用来网络通信必备的东西;
创建socket创建套接字:
import socket soc = socket.socket(AddressFamily, Type)函数socket.socket创建一个socket,该函数有两个参数:
Address Family:可选 AF_INET(用于internet进程间通信)和AF_UNIX(用于同一台机器进程间通信);
Type:套接字类型,可选 SOCK_STREAM(流式套接字,主用于TCP协议)/SOCK_DGRAM(数据报套接字,主用于UDP套接字);
创建tcp套接字
import socket soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM) ... soc.close()创建udp套接字
import socket soc = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) ... soc.close() udp udp使用socket发送数据在同一局域网内发消息;
如果用虚拟机和windows,要用桥接模式,确保在同一局域网内;
udp发送数据的几种情况:
在固定数据的引号前加b,不能使用于用户自定义数据;
用户自定义数据,并进行发送,使用.encode("utf-8")进行encode编码
用户循环发送数据
用户循环发送数据并可以退出
只贴出最后一种情况,即完整代码
import socket def main(): # 创建一个udp套接字 udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) while 1: # 从键盘获取要发送的数据 send_data = input("请输入你要发送的数据:") if send_data == "exit": break # 使用套接字收发数据 udp_socket.sendto(send_data.encode("utf-8"), ("193.168.77.1", 8080)) # 关闭套接字 udp_socket.close() if __name__ == "__main__": main() udp接收数据接收到的数据是一个元组,元组第一部分是发送方发送的内容,元组第二部分是发送方的ip地址和端口号;
import socket def main(): udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) localaddr = ('', 8080) udp_socket.bind(localaddr) # 必须绑定自己电脑的ip和端口 # 接收数据 recv_data = udp_socket.recvfrom(1024) # recv_data这个变量存储的是一个元组,例如 (b'hahaha', ('192.168.77.1', 8888)) recv_msg = recv_data[0] send_addr = recv_data[1] # print("%s 发送了:%s" % (str(send_addr), recv_msg.decode("utf-8"))) # linux发送的数据用utf8解码 print("%s 发送了:%s" % (str(send_addr), recv_msg.decode("gbk"))) # windows发送的数据用gbk解码 udp_socket.close() if __name__ == "__main__": main() udp接发数据总结发送数据的流程:
创建套接字
发送数据
关闭套接字
接收数据的流程:
创建套接字
绑定本地自己的信息,ip和端口
接收数据
关闭套接字
端口绑定的问题如果在你发送数据时,还没有绑定端口,那么操作系统就会随机给你分配一个端口,循环发送时用的是同一个端口;
也可以先绑定端口,再发送数据。
udp发送消息时自己绑定端口示例
import socket def main(): # 创建一个udp套接字 udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # 绑定端口 udp_socket.bind(('192.168.13.1', 8080)) while 1: # 从键盘获取要发送的数据 send_data = input("请输入你要发送的数据:") if send_data == "exit": break # 使用套接字收发数据 udp_socket.sendto(send_data.encode("utf-8"), ("193.168.77.1", 8080)) # 关闭套接字 udp_socket.close() # 按ctrl+c退出 if __name__ == "__main__": main()但应注意,同一端口在同一时间不能被两个不同的程序同时使用;
单工,半双工,全双工 单工半双工全双工的理解单工:
只能单向发送信息,别人接收,别人不能回复消息,比如广播;
半双工:
两个人都能发消息,但是在同一时间只能有一个人发消息,比如对讲机;