Python 简单的socket编程(TCP)

系统 1546 0
  • 问题描述

个人认为,Socket编程是一个很重要的东西,无论是什么语言,用到Socket编程的一定有很多,所以,学习Socket编程是很重要的。个人学习Socket编程的原因,是因为自己觉得学Python有一段时间了,想要做个桌面应用程序出来,首先要搞定Socket编程,所以就开始学习了。下面介绍一下简单的Socket编程。

 

  • 解决方法

直接上代码,分为两个程序,一个是服务端的程序,用于接收其他的tcp连接,另一个是客户端的程序,用于请求连接。

首先,是服务端的程序:

            
              import socket

HOST = '0.0.0.0'  
PORT = 8000

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    s.bind((HOST, PORT))
    s.listen()
    while True:
        conn, addr = s.accept()
        print('Connected by', addr)
        while True:
            data = conn.recv(1024)
            if not data:
                break
            conn.sendall(data)
            print('get data ', data.decode('utf-8'))

            
          

这里host写的是0.0.0.0,指的是允许所有的IP进行tcp连接,如果设置为127.0.0.1,则就是本机访问,除了服务器程序运行以外的机器无法进行访问。

port就是指端口,指定tcp通过哪个端口进行连接

接下来就是生成socket对象,这里需要说明的是,有的程序生成socket对象使用的是 

            
              sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            
          

这个和上面代码中的 

            
              with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
            
          

 效果是一样的,问题在于,使用第一个代码时,我们进行完连接以后,需要手动的进行close。

            
              sock.close()
            
          

 而如果使用with语句,那么我们就不需要自己手动设置close,程序能够帮助我们自动关闭,如果你能理解文件操作里面的open 和 with open,那么我相信你也能理解这里with的意思。

socket.AF_INET 指通过ipv4连接,socket.SOCK_STREAM 指通过tcp连接

s.bind 指将套接字绑定到我们之前指定的地址

s.listen 指开始进行监听tcp连接

接下来进行死循环

conn, addr = s.accept()       接受TCP链接并返回(conn, address),其中conn是新的套接字对象,可以用来接收和发送数据,address是连接客户端的地址。

接下来再次进行死循环,上一次的死循环,能够让我们建立连接以后,发送多次消息,而这一次的死循环,是循环接收数据,因为我们接收数据是

            
              data = conn.recv(1024)
            
          

即接收1024字节,所以,如果我们发送的字节超过了1024字节,那么我们就进行下一次循环,继续接收1024字节,就一直死循环,直到所有的字节接受完,然后就 break 退出

conn.sendall(data) 指返回数据给客户端,sendall指一次性发送所有的数据,因为如果我们要发送的数据超过了1024字节,用send方法发送数据的话,一次性是发送不完的,是需要用死循环进行发送的, 但是如果我们用sendall,就不用死循环发送了。需要注意的是,我们收到或者发送的数据是bytes格式的,所以我们在发送数据时,需要用encode,将接收的数据变成字符串时,我们需要用decode。

 

接下来是客户端程序

            
              import socket

HOST = '192.168.5.135'  # 服务器的主机名或者 IP 地址
PORT = 8000        # 服务器使用的端口

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    s.connect((HOST, PORT))
    s.settimeout(5)
    while True:
        try:
            a = input('please input:')
            s.sendall(a.encode('utf-8'))
            data = s.recv(1024)
            print('Received', data.decode('utf-8'))
        except socket.timeout as e:
            print('time out')
            continue
            
          

 host指服务器ip

port指服务器端口

使用with 语句创建socket对象

s.connect进行tcp连接

s.settimeout(5)设置超时时间,如果一段5秒以后没有还是没有和服务器进行正常的通信,那么,就抛出socket.timeout异常

接下来进行死循环,我们使用input发送我们想发送的字符串

然后使用sendall进行发送,发送之前使用encode将字符串转为bytes格式

接下来进行recv,接收服务器返回来的数据

打印输入服务器数据

如果我们捕获了socket.timeout异常,则进行下一次的数据发送

下图为客户端程序输出:

下图为服务端程序输出:

至此,简单的tcp程序就完成了

 

  • 总结

有了上面的程序,再进行一点异常的捕获、优化,我们就能够进行相对稳定的tcp连接了, 如果后面有碰到多连接的情况,再进行处理。


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论