python 网络编程

网络编程的基本概念:

网络的七层:

第七层:应用层

第六层:表示层

第五层:会话层

第四层:传输层

第三层:网络层

第二层:数据链路层

第一层:物理层


IP地址分为A,B,C,D,E五类。

网络号:用于识别主机所在的网络;

主机号:用于识别该网络中的主机。

其中A类分配给政府机关使用,B类地址给大中型企业使用,C类地址给个人使用。这三种是主要的。IP地址分为五类,A类保留给政府机构,B类分配给中等规模的公司,C类分配给任何需要的人,D类用于组播,E类用于实验,各类可容纳的地址数目不同。

其中A类、B类、和C类这三类地址用于TCP/IP节点,其它两类D类和E类被用于特殊用途。
A、B、C三类IP地址的特征:当将IP地址写成二进制形式时,A类地址的第一位总是O,B类地址的前两位总是10,C类地址的前三位总是110。

1. A类地址

⑴ A类地址第1字节为网络地址,其它3个字节为主机地址。

⑵ A类地址范围:1.0.0.1—126.155.255.254

⑶ A类地址中的私有地址和保留地址:

① 10.X.X.X是私有地址(所谓的私有地址就是在互联网上不使用,而被用在局域网络中的地址)。

② 127.X.X.X是保留地址,用做循环测试用的。

 2. B类地址
 ⑴ B类地址第1字节和第2字节为网络地址,其它2个字节为主机地址。
 ⑵ B类地址范围:128.0.0.1—191.255.255.254
 ⑶ B类地址的私有地址和保留地址
 ① 172.16.0.0—172.31.255.255是私有地址
 ② 169.254.X.X是保留地址。如果你的IP地址是自动获取IP地址,而你在网络上又没有找到可用的DHCP服务器。就会得到其中一个IP。

 3. C类地址
 ⑴ C类地址第1字节、第2字节和第3个字节为网络地址,第4个个字节为主机地址。另外第1个字节的前三位固定为110。
 ⑵ C类地址范围: 192.0.0.1—223.255.255.254
 ⑶ C类地址中的私有地址:
 192.168.X.X 是私有地址。

 4. D类地址
 ⑴ D类地址不分网络地址和主机地址,它的第1个字节的前四位固定为1110。
 ⑵ D类地址范围: 224.0.0.1—239.255.255.254

 5. E类地址
 ⑴ E类地址也不分网络地址和主机地址,它的第1个字节的前五位固定为11110。
 ⑵ E类地址范围: 240.0.0.1—255.255.255.254

TCP TCP是一种面向连接的、可靠的、基于字节流的传输层通信协议,它完成第四层传输层所指定的功能..

UDP: UDP是一种简单的面向数据报、无连接、传输层协议,并且保留了信息边界。UDP不提供错误校正,不保证有序,无法去重复,没有流量控制和拥塞控制,不能保证数据一定到达目的地,但是可以通过校验和提供错误侦测。UDP提供的的是不可靠传输,因此要有应用层来提供这些功能。

 端口端口号的范围从0到65535,0~1024端口系统已分配,后面可以使用。一个端口就是一个连接应用。

Socket(套接字):

Socket类型:

Socket.AF_UNIX     : 只能够用于单一的Unix系统进程间通信

Socker.AF_INET     : 服务器之间网络通信

Socket.AF_INET6   :  IPv6(现在很少使用IPv6)

Socket.SOCK_STREAM  : 流式socket,for TCP

Socket.SOCK_DGRAM    :     数据报式socket, forUDP

Socket.SOCK_RAW :     原始套接字,普通的套接字无法处理ICMP,IGMP等网络报文,而SOCK_RAW可以;其次,SOCK_RAW也可以处理特殊的IPv4报文;此外,利用原始套接字,可以通过IP_HDRINCL套接字选项由用户构造IP头.

Socket.SOCK_SEQPACKET  :  可靠的连续数据包服务 

Socket函数:

1.服务端socket函数:

s.bind(address):   将套接字绑定到地址,在AF_INET下,以元组(host,port)的形式表示地址.

:host表示ip地址,port表示对端口

s.listen(backlog): 开始监听TCP传入连接,backlog指定在拒接连接之前,操作系统可以挂起最大连接数量.该值至少为1,大部分应用程序设为5就可以了.

s.accept()  :    表示服务器等待连接,接受TCP连接并返回(conn,address),其中conn是新的套接字对象,可以用来接收和发送数据.address是连接客户端的地址.

2.客户端socket函数:

s.connect(address)  :      (用于服务器连接,)连接到address处的套接字.一般address的格式为元组(hostname,port),如果连接出错,返回socket.error错误

s.connect_ex(address) :  功能与connect(address)相同,但是成功返回0,失败返回error的值

3.公共socket函数:

s.recv(bufsize[,flag]):           接受TCP套接字的数据.数据以字符串形式返回,bufsize指定要接收的最大数据量.flag提供有关消息的其他信息,通常可以忽然.

s.send(string[,flag]) :      发送TCP数据.将string中的数据发送到连接的套接字.返回值是要发送的字节数量,该数量肯小于string的字节大小.

s.sendall(string[,flag]):         完整发送TCP数据.将string中的数据发送到连接的套接字,但在返回之前会尝试发送所有数据.成功返回None,失败则抛出异常.

s.recvfrom(bufsize[,flag]):    接受UDP套接字的数据.与recv类似,但返回值是(data,address).其中data是包含接收数据的字符串,address是发送数据的套接字地址.

s.sendto(string[,flag],address):        发送UDP数据.将数据发送到套接字,address是形式为(ipaddr,port)的元组,指定远程地址,返回值是发送的字节数.

s.close(): 关闭套接字

s.getpeername():  返回连接套接字的远程地址,返回值通常是元组(ipaddr,port)

s.setsockname():  返回套接字自己的地址.通常是一个元组(ipadd,port)

s.setsockopt(level,optname,value) : 设置给定套接字选项的值.

s.getsockopt(level,optname,[,buflen]):        返回套接字选项的值

s.settimrout(timeout):           设置套接字操作的超时期,timcout是一个浮点数,单位是秒.值为None表示没有超时期.一般,超时期应该在刚创建套接字时设置,因为它们可能用于连接的操作

s.gettimeout():     返回当前超时期的值,单位是秒,如果没有设置超时期,则返回None

s.fileno():  返回套接字的文件描述符.

s.setblocking(flag):         如果flag为0,则将套接字设为非阻塞模式(默认值),非阻塞模式下,如果调用recv()没有发现任何数据,或者scnd()调用无法立即发送数据,那么将引起socket.error异常.

s.makefile()  :      创建一个与该套接字相关连的文件

 

要使用scoket.scoket()函数来创建套接字.其语法如下:

导入模块:import   socket

创建TCP socket: s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)

创建 UDP socket: s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)

 下面例子实现一个简单的服务器与客户端的通话:

服务器:

import socket,threading
secv=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
secv.bind(("127.0.0.1",9999))
print("服务器已启动")
secv.listen(5)
c=secv.accept()
print(c)
def myrerv(c):
    while True:
        msg = c[0].recv(1024)#接收消息
        print(msg.decode())
threading._start_new_thread(myrerv,(c,))
def myinput():
    while True:
        msg=input()
        c[0].send(msg.encode())#服务器发送消息
threading._start_new_thread(myinput())
客户端:

import socket,threading
client=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
client.connect(("127.0.0.1",9999))#ip127.0.0.1代表本机的ip,9999是端口号,是自己设置的但是服务器和客户端的端口号要一致
print("客户端已连接")
def myrerv(c):
    while True:
        msg = c.recv(1024)#接收消息
        print(msg.decode())
threading._start_new_thread(myrerv,(client,))
def myinput():
    while True:
        msg=input("某某说的话:)
        client.send(msg.encode())
threading._start_new_thread(myinput())
这只是一个服务器与客户端的通话,当我们需要实现多个客户端与服务器通话时实现群聊时,我们需要对服务器代码进行优化一下,代码如下:
import socket,threading
sercv=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
sercv.bind(("127.0.0.1",9999))
print("服务器已连接!")
sercv.listen(5)
msg=None
lock=threading.Lock()
mythread=threading.Condition(lock=lock)
def server_recv(c,a):
    global msg
    while True:
        mystr=c.recv(1024)
        mythread.acquire()
        msg=str(a) + mystr.decode()
        print(msg)
        mythread.notify_all()
        mythread.release()

def server_send(c):
    global msg
    while True:
        mythread.acquire()
        mythread.wait()
        mythread.release()
        c.send(msg.encode())
        print(msg)
while True:
    c,a=sercv.accept()
    threading._start_new_thread(server_recv,(c,a))
    threading._start_new_thread(server_send,(c,))
注:在通话时必须先启动服务器代码否则会报异常.

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值