zoukankan      html  css  js  c++  java
  • python实现两台不同主机之间进行通信(客户端和服务端)——Socket

    大家好,我是辰哥~

    今天教大家通过Python进行Socket网络编程

    (做一个聊天程序)

    可以实现在不同的主机(电脑)之间进行通话。

    具体效果如何,接着往下看

    可以看到客户端(上方)向服务器端(下方)发送了内容,服务器端进行了回复

    【备注:客户端是我的本机,服务器是另一条主机(阿里云服务器)】

    两台主机的目的:验证两台主机可以相互通信

    socket

    先简单给大家介绍一下什么是socket,socket(简称 套接字) 是进程间通信的一种方式,它与其他进程间通信的一个主要不同是:它能实现不同主机间的进程间通信。

    我们网络上各种各样的服务大多都是基于 Socket 来完成通信的,例如浏览网页、QQ 聊天、收发 email 等等

    简单的说:socket可以实现不同主机间进行通信

    socket通信的条件:IP和端口

    ip相信大家都陌生了,每一台主机都有一个ip,不同主机之间通信的首要前提就是ip可以互访,此外还有一个条件就是端口,比如我们经常听到的80端口,3306端口,8080端口等。

    主机中的数据是通过端口发送和接收,需要将对应端口打开才能进行通信。

    形象比喻

    ip相当于家庭地址,端口相当于门或者窗户

    例子:

    (主机A)快递员要想将快递(数据)送到你手中(另一台主机B),需要知道你家的地址(主机B的ip),到你家门口后,需要你打开门(主机B的端口)才能拿到快递(数据)。

    这里需要分服务端和客户端,客户端发送(主机A),服务器接收(主机B),当然了,每一台主机可以充当两个角色(既是客户端,也是服务器),这样就可以实现两台主机之间相互发送和接收。

    看到这里之后,相信大家都清楚socket在实现不同主机之间通信的大概意思了,下面开始Python代码实现。

    客户端实现过程

    先来分析客户端(主机A)的实现过程

    from socket import *
    # 1.创建套接字
    tcp_socket = socket(AF_INET,SOCK_STREAM)
    # 2.准备连接服务器,建立连接
    serve_ip = "服务器端(主机B)的IP"
    serve_port = 8000  #端口,比如8000
    tcp_socket.connect((serve_ip,serve_port))  # 连接服务器,建立连接,参数是元组形式
    
    

    首先与服务器接收端(主机B)建立连接,连接条件(主机B的ip和端口),这里的端口8000是指将数据发送到主机B的端口(主机B到时候会监听8000端口,然后进行接收数据)

    #准备需要传送的数据
    send_data = "今天是2021年08月29日,辰哥给服务器端发送数据了"
    tcp_socket.send(send_data.encode("gbk")) 
    #从服务器接收数据
    #注意这个1024byte,大小根据需求自己设置
    from_server_msg = tcp_socket.recv(1024)
    #加上.decode("gbk")可以解决乱码
    print(from_server_msg.decode("gbk"))  
    #关闭连接
    tcp_socket.close()
    

    send_data是往服务器端(主机B)发送的内容,from_server_msg是服务器端(主机B)往客户端(主机A)发送的内容

    客户端的代码就结束了

    服务器实现过程

    分析服务器端(主机B)的实现过程

    from socket import  *
    #创建套接字
    tcp_server = socket(AF_INET,SOCK_STREAM)
    #绑定ip,port
    #这里ip默认本机
    address = ('',8000)
    tcp_server.bind(address)
    # 启动被动连接
    #多少个客户端可以连接
    tcp_server.listen(128)  
    #使用socket创建的套接字默认的属性是主动的
    #使用listen将其变为被动的,这样就可以接收别人的链接了
    

    服务器端(主机B)ip可以留空(默认本机),端口8000(因为客户端往8000端口发送数据,所以服务器需要监听的端口也是8000,与客户端的端口一致)

    # 创建接收
    # 如果有新的客户端来链接服务器,那么就产生一个新的套接字专门为这个客户端服务
    client_socket, clientAddr = tcp_server.accept()
    
    client_socket用来为这个客户端服务,相当于的tcp_server套接字的代理
    tcp_server_socket就可以省下来专门等待其他新客户端的链接
    这里clientAddr存放的就是连接服务器的客户端地址
    #接收对方发送过来的数据
    from_client_msg = client_socket.recv(1024)#接收1024给字节,这里recv接收的不再是元组,区别UDP
    print("接收的数据:",from_client_msg.encode("gbk"))
    #发送数据给客户端
    send_data = client_socket.send("客户端你好,服务器端收到,公众号【Python研究者】".encode("gbk"))
    #关闭套接字
    #关闭为这个客户端服务的套接字,就意味着为不能再为这个客户端服务了
    #如果还需要服务,只能再次重新连
    client_socket.close()
    

    from_client_msgs 是服务器端(主机B)接收到来自客户端(主机A)发送过来的数据send_data 是服务器端(主机B)往客户端(主机A)发送过去的数据

    服务器端的代码就结束了

    提醒:服务器端的8000端口需要开启,不然无法进行通信

    演示

    先启动(执行)服务器端(主机B)的程序,再执行客户端(主机A)

    可以看到客户端(上方)向服务器端(下方)发送了内容,服务器端进行了回复

    发送和响应内容:

    客户端发送:今天是2021年08月29日,辰哥给服务器端发送数据了

    服务器端接收并回复给客户端:客户端你好,服务器端收到,公众号【Python研究者】

    实现持续通信过程

    上方动图演示的是客户端和服务端的一次通信过程,可以将客户端的发送和服务端的接收放到循环中,实现持续通信过程。

    客户端

    while(1):
        send_data = input("请输入内容:")
        #send_data = "今天是2021年08月29日,辰哥给服务器端发送数据了"
        tcp_socket.send(send_data.encode("gbk"))
        if send_data == "exit":
             break;
        #从服务器接收数据
        #注意这个1024byte,大小根据需求自己设置
        from_server_msg = tcp_socket.recv(1024)
        #加上.decode("gbk")可以解决乱码
        print(from_server_msg.decode("gbk"))
    #关闭连接
    tcp_socket.close()
    

    服务端

    
    while(1):
        #接收对方发送过来的数据
        from_client_msg = client_socket.recv(1024)#接收1024给字节,这里recv接收的不再是元组,区别UDP
        if(from_client_msg=="exit"):
            break
        print("接收的数据:",from_client_msg.decode("gbk"))
        now_time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
        #发送数据给客户端
        send_data = client_socket.send((str(now_time)+" 服务端:客户端你好,服务器端收到,公众号【Python研究者】").encode("gbk"))
        #关闭套接字
        #关闭为这个客户端服务的套接字,就意味着为不能再为这个客户端服务了
        #如果还需要服务,只能再次重新连
    client_socket.close()
    

    客户端可以持续给服务端发送数据,服务器接收数据后打印并返回数据给客户端

    服务端返回的内容:

    当前系统时间+服务端:客户端你好,服务器端收到,公众号【Python研究者】

    最后当客户端输入:exit,则断开与服务端的连接

    耐得住寂寞,才能登得顶
    Gitee码云:https://gitee.com/lyc96/projects
  • 相关阅读:
    [BZOJ1934][Shoi2007]Vote 善意的投票[最小割]
    [BZOJ1066][SCOI2007]蜥蜴[最大流]
    [BZOJ2818][P2568]Gcd[欧拉函数]
    [BZOJ2208][P4306][JSOI2010]连通数[bitset优化floyd]
    [BZOJ1877][SDOI2009]晨跑[最大流+费用流]
    [BZOJ1040][P2607][ZJOI2008]骑士[树形DP+基环树]
    [BZOJ5347]冒泡排序[思维]
    [BZOJ2875][Noi2012]随机数生成器[等比数列求和+取模]
    [bzoj2809] 派遣
    [bzoj1965] 洗牌
  • 原文地址:https://www.cnblogs.com/chenlove/p/15208755.html
Copyright © 2011-2022 走看看