python的网络与套接字

1 网络
1.1 使用网路的目的
使用网络可以把多方链接在一起,然后可以进行数据传递
所谓的网络编程,实现的是进程之间的通信
1.2 ip地址
ip地址可以理解为家庭地址。快递员通过家庭地址,进行转发货物,那么,ip地址在网络上就是标志你所在的网络和主机
ip地址分为网络号和主机号
在这么多ip地址中,国际规定有一部分ip地址是用于我们的局域网使用,也就属于私网ip,不属于公网,他们的范围是:
10.0.0.0~10.255.255.255
172.16.0.0~172.31.255.255
192.168.0.0~192.168.255.255
ip地址 127.0.0.1~172.255.255.255用于回路测试
如:127.0.0.1可以代表本机ip地址
1.3 端口
ip是用来标志网络主机,而端口是用来标志主机中的一个唯一的应用程序。
知名端口:小于1024,
动态端口:大于1024,我们在发送数据,可以指定自己的应用程序的动态端口,也可以由操作系统随机分配一个端口,当我们结束链接时,由操作系统分配的动态端口会被回收,下次使用该应用程序,又会分配一个新的随机端口
注:在主机中,不同应用程序,不能用相同端口
1.4 利用socket进行数据传输
1.4.1
发送数据步骤:

  1. 创建socket
  2. 发送数据
  3. 关闭socket
import socket


def main():
    #创建一个套接字
    udp_socket=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
    #使用套接字接发数据
    udp_socket.sendto("内容",("192.168.10.25",8080))
    #关闭套接字
    udp_socket.close()

if __name__ =="__main__":
main()




接受数据步骤:
1.	创建套接字
2.	绑定本地套接字
3.	使用套接字接受数据
4.	打印数据
5.	关闭套接字
代码:

import socket


def main():
    # 1.创建套接字
    udp_socket=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
    # 2.绑定套接字
    local=('',7878)
    udp_socket.bind(local)
    # 3.接受数据
    info=udp_socket.recvfrom(1024)
    # info接受的是一个元组(接收的数据,(发送方的ip,端口号))
    
    # 4.输出接受的内容
    str_add=info[1]
    str_msg=info[0]
    print(info)
    print("%s:%s"%(str(str_add),str_msg.decode("gbk")))
    # 单独打印接受的内容和数据
    # 5.关闭套接字
    udp_socket.close()

if __name__ == "__main__":
main()

> 套接字属于全双工


1.5	手机通讯系统案例
利用套接字实现既能发数据也能收数据的一个小代码。
import socket


def send(udp_socket):
    """发送数据"""
    socket_ip=input("请输入IP:")
    socket_port=int(input("请输入port:"))
    socket_info=input("请输入您要发送的内容:")
    udp_socket.sendto(socket_info.encode("utf-8"),(socket_ip,socket_port))

        
def rmcv(udp_socket):
    """接收数据"""
    msg=udp_socket.recvfrom(1024) 
    print("%s:%s" % (str(msg[1]),msg[0].decode("utf-8")))    
    

def main():
    # 创建套接字
    udp_socket=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
    # 绑定套接字
    local_add=("",2550)
    udp_socket.bind(local_add)
    while True:
        print("-------手机通讯系统--------")
        print("1.发送数据")
        print("2.接受数据")
        print("3.退出系统")
        num=input("请输入您要选择的功能")
        if num == "1":
            # 调用发送数据函数
            send(udp_socket)
        elif num == "2":
            # 调用接受数据函数
            rmcv(udp_socket)
        elif num == "3":
            break
        else:
            print("您输入的有误,请重新输入")


if __name__ == "__main__":
    main()


2	Tcp
2.1	Tcp介绍
Udp通信模型:
Udp通信模型中,在通信开始之前,不需要建立连接,只需要发送数据即可。(不安全,但快速)
Tcp协议:传输控制协议(速度慢,但传输可靠):
Tcp通信经过三个步骤:建立连接,收发数据,关闭连接


2.2	Tcp客户端
所谓的客户端:就是需要被服务的一方,所谓的服务器就是,提供服务的一方
Tcp客户端连接服务器流程:
	创建套接字
	连接服务器
	发送数据
	关闭套接字
案例:
import socket


def main():
    # 创建tcp套接字
    tcp_socket=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    # 为本机绑定端口
    tcp_socket.bind(("",55007))
    # 建立连接
    server_ip=input("请输入您要连接的服务器IP:")
    server_port=int(input("请输入服务器的Port:")) 
    tcp_socket.connect((server_ip,server_port))
    # 发送数据
    data=input("请输入您要发送的数据")
    tcp_socket.send(data.encode("gbk"))
    # 关闭tcp套接字
    tcp_socket.close()
if __name__ == "__main__":
main()
2.3	tcp服务器
tcp服务器的步骤:
1.	建立套接字 
tcp_server_socket=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
2.	绑定本地的信息 
tcp_server_socket.bind(("",55014))    #55014为端口号,自己设定
3.	监听(监听是否有客户端建立连接)
tcp_server_socket.listen()
4.	接受连接
new_tcp_socket,client_socket =tcp_server_socket.accept()
在接受连接时,会有俩个返回值,第一个返回值是,新的套接字,主要为了与该用户进行数据之间的传递,而另一个返回值是代表客户端的ip和端口号。
案例:
import socket


def main():
    # 创建套接字
    tcp_server_socket=socket.socket(socket.AF_INET,socket.SOCK_STREAM)

    # 绑定端口
    tcp_server_socket.bind(("",55014))
    
    # 被动监听,让默认的套接字由主动变为被动listen
    tcp_server_socket.listen()

    # 循环目的:调用多次accept,从而为多个客户端服务
    while True:
        print("正在等待连接。。。")
        # 接受链接
        new_tcp_socket,client_socket =tcp_server_socket.accept()
        print("连接成功")
        
        # 向服务器发送提示数据
        new_tcp_socket.send("连接成功,请发送数据给服务器".encode("gbk"))

        # 循环目的:为同一个客户端 服务多次
        while True:

        
            # 接受客户端的数据
            data=new_tcp_socket.recv(1024)
            print(data.decode("gbk"))
            # 当客户端关闭连接时,服务器端自动断开与该用户的连接
            if data:
                
                # 向服务器发送数据
                new_tcp_socket.send("您发送的数据已经收到,请问还有其他需求吗?".encode("gbk"))
            else :
                break
                
        # 关闭服务器与客户机之间连接产生的套接字,既关闭accept返回的套接字,不为这个用户服务
        new_tcp_socket.close()

    # 关闭被动监听的套接字,既不等待新的用户的到来
    tcp_server_socket.close()
    
    
if __name__ == "__main__" :
    main()

案例:文件下载器
1.	f=open(“xxx”)
try :
	f.read()
except:
	f.close
这个语句可以这样写:
	with open(“xxxx”) as f
	f.read() 
如果f.read()出现异常,会自动关闭文件,不需要自己f.close()

客户端代码:
import socket


def main():
    # 创建tcp套接字
    tcp_client_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    
    # 绑定ip 端口
    tcp_client_socket.bind(("",54621))
    
    # 连接服务器
  
    tcp_client_socket.connect(("192.168.3.1",52548))
    print("连接服务器成功")

    # 向服务器发送要下载的文件名
    download_filename=input("请输入要下载的文件名")
    tcp_client_socket.send(download_filename.encode("utf-8"))
    
    # 接受服务传过来的数据
    download_data=tcp_client_socket.recv(1024*1024)
    print("打印一下接受的数据")
    print(download_data)
    

    # 将数据写入本地
    with open("【新】"+download_filename,"wb") as f :
        f.write(download_data)
    
    # 关闭套接字
    tcp_client_socket.close()


if __name__ == "__main__":
main()
服务端代码:
import socket

def send(filename):
    data = None
    try :
        f=open(filename,"rb")
        data=f.read()
        f.close()
    except Exception as ret :
        print("你要下载的文件不存在")
    return data
        


def main():
    # 创建服务器套接字
    tcp_server_socket=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    
    # 绑定ip和port
    tcp_server_socket.bind(("",52548))
    # 将主动改为被动监听
    tcp_server_socket.listen(128)
    # 接受连接
    new_socket,client_ip_socket=tcp_server_socket.accept()

    while True:
        # 接受要下载的文件名
        download_filename=new_socket.recv(1024*1024)
        if download_filename:
            # 打开文件
            data=send(download_filename)
        
        # 将数据发送给客户端
        if data :
            new_socket.send(data)
        
    new_socket.close()    
    # 关闭套接字
    tcp_server_socket.close()


if __name__ == "__main__":
    main()
2.4	tcp复习知识点
1.	tcp服务器一般情况下都需要绑定,否则客户端都找不到这个服务器
2.	tcp客户端一般不绑定,因为是主动连接服务器,所以只要绑定好服务器的ip、port等信息就好,本地客户极端可以随机
3.	tcp服务器中通过listen可以将socket创建出来的主动套接字变为被动的,这是做tcp服务器时必须要做的
4.	当客户端需要连接服务器时,就需要使用connect进行链接,udp时不需要链接的而是直接发送,但是tcp必须先链接,只有链接成功才能通信
5.	当一个tco客户端连接服务器时,服务器就会有1个新的套接字,这个套接字用来标记这个客户端,单独为这个客户端服务
6.	Listen后的套接字是被动套接字,用来接受新的客户端的链接请求的,而accept返回的新套接字是标记这个新客户端的
7.	关闭listen后的套接字意味着被动套接字关闭了,会导致新的客户端不能够链接服务器,但是之前已经链接成功的客户端正常通信
8.	关闭accpet返回的套接字意味着这个客户端已经服务完毕
9.	当客户端的套接字调用后,服务器端会recv解堵塞,并且返回的长度为0,因此服务器可以通过返回的数据的长度来区别客户端是否已经下线


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值