将目前的一些知识点做一个总结
从1.TCP/IP网络,2.c/s,b/s架构,3.HTTP协议,4.socket编程四部分来阐述:
1.TCP/IP网络
TCP/IP网络协议栈分为应用层(Application)、传输层(Transport)、网间层(Network)和网络接口层(Link)四层。
网际层也称为:网络层
网络接口层也称为:链路层
协议就是用来完成进程之间通讯的一种规范,
Tcp/ip协议它不是一个协议,而是一个协议族,所有协议的一个总称,它是用来规范网络当中传输信息或是电脑与电脑之间传输信息,Tcp/ip协议根据它所用的功能不一样分成了好几个层。
1.什么是网络?
网络就是一种辅助双方或者多方能够连接在一起的工具,然后可以进行数据传递
所谓的网络编程就是,让在不同的电脑上的软件能够进行数据传递,即进程之间的通信
2.什么是协议
为了解决不同种族人之间的语言沟通障碍,现规定国际通用语言是英语,这就是一个规定,这就是协议。计算机都遵守的网络通信协议叫做TCP/IP协议。因为互联网协议包含了上百种协议标准,但是最重要的两个协议是TCP和IP协议,所以,大家把互联网的协议简称TCP/IP协议。
pid可以在一台电脑上区分进程。
端口是通过端口号来标记的,端口号只有整数,范围是从0到65535
知名端口(Well Known Ports)范围从0到1023,80端口分配给HTTP服务,21端口分配给FTP服务。
动态端口的范围是从1024到65535,查看端口号是netstat -an
主机是通过“IP地址+端口号”区分不同的网络服务
地址就是用来标记地点的,ip地址是用来在网络中标记一台电脑的一串数字,在本地局域网中是唯一的。IP地址包括两部分:网络地址和主机地址
3.本地进程间的通讯
通讯ipc方式有很多,队列,同步(互斥锁,条件变量等),网络中的进程的通讯(在本地可以通过进程PID来唯一标识一个进程,网络层的“ip地址”可以唯一标识网络中的主机,传输层的“协议+端口”可以唯一标识主机中的应用程序(进程))。
2.socket
(简称套接字) 是进程间通信的一种方式,它与其他进程间通信的一个主要不同是:它能实现不同主机间的进程间通信
① Address Family:可以选择 AF_INET(用于 Internet 进程间通信)或者 AF_UNIX(用于同一台机器进程间通信),实际工作中常用AF_INET
② Type:套接字类型,可以是 SOCK_STREAM(流式套接字,主要用于 TCP 协议)或者 SOCK_DGRAM(数据报套接字,主要用于 UDP 协议)
创建一个tcp套接字 s=socket,socket(socket.AF_INET,socket.SOCK_STREAM)
创建一个udp套接字 s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
总结:拥有发送网络数据和接收网络数据的功能的对象称之为套接字。
改成桥接模式,网络调试助手也改到20段的,保证他们在同一个局域网中,ubuntu和windows在ubuntu中ifconfig查到的地址可以在windows中ping通,在windows中ipconfig查到的地址有时在ubuntu中没能ping通。
信息的发送
安装了ubuntu的,还可以用虚拟ip,如图中的192.168.126.1
使用python3往windows上发送数据:
在python2中可以不用加b
想要用
网络调试助手发送数据给飞秋,飞秋的端口号是2425
在网络调试助手中输入:1:123123:ycw:ycw-pc:32:hello
(32就是收到消息。)基本格式如下:版本号(现行IPMSG为版本为1):包编号:发送者姓名:发送者机器名:命令字:附加信息举例。
想使用程序给飞秋发送消息:
from socket import *
udpSocket=socket(AF_INET,SOCK_DGRAM)
udpSocket.sendto("1:123123:ycw:ycw-pc:32:hello",(192.168.20.116,2425))
用程序给网络调试助手发消息:
from socket import *
udpSocket = socket(AF_INET,SOCK_DGRAM)
udpSocket.sendto("haha",("192.168.20.116",8080)) #在python3中会报错误
用网络调试助手发消息给ubuntu,ubuntu来接收数据
一般情况下发送方是不绑定的,接收方需要绑定端口,绑定端口需要的数据类型是一个元组的类型,如果绑定的端口被注释掉了,就得不到数据了。
from socket import *
udpSocket=socket(AF_INET,SOCK_DGRAM)
udpSocket.bind(("",8787))
recvData=udpSocket.recvfrom(1024)
print(recvData)
让用户自己写ip,端口,内容,给网络调试助手发消息
from socket import *
udpSocket=socket(AF_INET,SOCK_DGRAM)
ip=input("ip")
port =int(input("port"))
Data = input("content")
udpSocket.sendto(Data.encode("gb2312"),(ip,port))
使用b“haha”跟使用encode(“utf8”)的效果是一样的,后面这种方法更通用。
解决ubuntu接收的数据乱码问题
from socket import *
udpSocket=socket(AF_INET,SOCK_DGRAM)
udpSocket.bind(("",8787))
recvData=udpSocket.recvfrom(1024)
content,info=recvData
print("content is %s"%content.decode("gb2312"))
decode是解码。encode是编码
聊天室
要求:模拟一个聊天室,显示所有接收到的数据
from socket import *
def main():
udpSocket=socket(AF_INET,SOCK_DGRAM)
udpSocket.bind(("",8787))
while True:
recvData=udpSocket.recvfrom(1024)
print("[%s]:%s"%(str(recvData[1],recvData[0].decode("gb2312")))
if __name__=='__main__':
main()
收到了数据,再给人原封不动的返回去,这样的服务器就叫做echo服务器。
在上面的那个代码中的while True前面定义一个num=1,在再recvData下面写一个udpSocket.sendto(recvData[0],recvData[1])
print("收到的第%s个数据,内容是%s"%(num,recvData[0].decode("gb2312")))
num+=1
udpSocket.close()
模拟QQ聊天-多线程
from threading import Thread
from socket import *
def recvData():
while True:
recvInfo = udpSocket.recvfrom(1024)
print(">>%s,%s"%(str(recvInfo[1]),recvInfo[0].decode("gb2312")))
def sendData():
while True:
sendInfo=input("<<")
udpSocket.sendto(sendInfo.encode("gb2312"),(zzip,zzport))
udpSocket=None
zzip=""
zzport=0
def main():
global udpSocket
global zzip
global zzport
zzip=input("对方ip")
zzport=int(input("port"))
udpSocket =socket(AF_INET,SOCK_DGRAM)
udpSocket.bind(("",7788))
tr=Thread(target=recvData)
ts=Thread(target=sendData)
tr.start()
ts.start()
tr.join()
ts.join()
if __name__=='__main__':
main()
线程与进程最大的区别在于:
全局变量共享不共享的问题,线程是可以共享全局变量的,而进程是不共享全局变量的。在一个函数里面声明udpSocket变量,想在另外二个函数里面不可以使用的,只有全局变量,或是传递过去才可以使用的。
什么时候写none???什么时候写” ”???什么时候写0???
如果将来这个变量存储的是字符串,那么默认的值就是一个空的字符串” ”,
如果将来这个变量存储的是数字类型的,那么默认的值就是一个0,
如果将来这个变量存储的是一个对象,那么默认的值就是一个None。
网络编程中的广播
广播只能在udp中使用,tcp中使用不了
#coding=utf-8import socket,sysdest=('',2425)
s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
s.setsockopt(socket.SOL_SOCKET,socket.SO_BROADCAST,1)
sendData ="1:123123:熊猫剧场:ycw-pc:32:电视剧"
s.sendto(sendData.encode("gb2312"),dest)
print("等待对方回复")
while True:
(buf,address) = s.recvfrom(2048)
print("is %s:%is"%(address,buf.decode("gb2312")))
网友评论