python学习心得之:socket实现终端对话

 
  我们可以使用python在本地搭建简易服务器,所谓简易服务器,其实便是两台计算机通过python实现通话,就像我们使用的qq聊天软件。
  在实现即时通话之前,我们需要进行一个基础知识的学习-client嵌套字。

一、socket

定义
socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,应用程序通常通过"套接字"向网络发出请求或者应答网络请求。

 
  我们在可以不去深究scoket内在的运行的机制,在使用python编程时只需要了解并会使用scoket的一些内建函数便可以实现基本的功能,以下是我总结的一些内建函数,秉着用多少学多少的原则,我这里并不列举所有的内容。

序号 内建函数 参数 返回值 功能
服务器端
1 bind((host, port)) 这里的(host,port)不是两个参数,而是一个元组形式参数,其中host为主机名,port为端口 绑定地址到嵌套字
2 listen(num) num为指定在拒绝连接之前,可以挂起的最大连接数量,最小为1,最大为5 开始TCP监听
3 accept() 这里的返回值是一个元组形式,内容较为复杂,可以不去深究,我们可以利用这个返回值去进行收发数据,例如在我电脑上返回值如下(<socket.socket fd=4, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=(‘192.168.0.100’, 8002), raddr=(‘192.168.0.100’, 50688)>, (‘192.168.0.100’, 50688)) 本方法会阻塞线程,直到有客户端连入
客户端
1 connect((host, port)) 这里的参数仍然是一个元组形式,内容和服务器端bind()方法的参数是一样的 实现与服务器的连接
公共方法
1 recv() 不详细解释 对方发送的数据 接收数据
2 send() 要发送的数据 发送数据

 
  socket内建的方法还有很多,本次练习只用到这些,先介绍这么多

二、socket实现本地通话

 
  我们先来看一段代码

#服务器端
import socket
s = socket.socket()
host = socket.gethostname() #获取主机名
port = 9000 #端口
s.bind((host, port))
s.listen(5)
while True:
    c, addr = s.accept()        #阻塞进程,等待客户端接入
    c.send(bytes("连接成功?",encoding="utf-8")) #客户端接入,发送数据
    c.close()

#客户端
import socket
s = socket.socket() 
host = socket.gethostname() #获取主机名
port = 9000 #端口
s.connect((host, port))     #客户端接入
mes = str(s.recv(1024),encoding = "utf-8") #接收客户端数据
print("服务器:{}".format(mes)) #打印输出
s.close()

 
  这段代码比较简单,将我们上面介绍的内建方法做一个调用,然后讲收到的数据做一个打印输出,各位不妨试一试,在同一台电脑上,打开两个终端,分别运行两个程序,你大概会得到如下的结果。
python学习心得之:socket实现终端对话
  到这里,我们实现了一个最简单的功能:连接服务器-接受服务期的消息-打印输出
  然而这显然是不够的,我们可以看到,左上角的服务器端一直在运行,而左下角的客户端在接收数据后就退出了,而如何实现他们之间的对话?
  我们接着看下一段代码:

#服务器端
import socket
s = socket.socket()
host = socket.gethostname()
port = 9000
s.bind((host, port))

s.listen(5)
while True:
    print('等待用户连接……')
    c, addr = s.accept()        #阻塞进程,等待客户端接入
    print('用户已连接 address:{}\n服务器:请问需要什么帮助'.format(addr))
    c.send(bytes("请问需要什么帮助?",encoding="utf-8"))
    while True:
        mes = str(c.recv(1024),encoding = "utf-8")
        print("客户端:{}".format(mes))
        mes = input("服务器:")
        c.send(bytes(mes,encoding="utf-8"))

    c.close()


import socket
s = socket.socket()
host = socket.gethostname()
port = 9000
s.connect((host, port))     #客户端接入
while True:
    mes = str(s.recv(1024),encoding = "utf-8")
    print("服务器:{}".format(mes))
    mes = input("客户端:")
    s.send(bytes(mes,encoding="utf-8"))
s.close()

 
  在这段代码中,我对界面做了一些优化,我们可以看到,借用一个简单的循环,我们实现了两个终端之间的对话,你可以尝试一下,在同一台电脑上,打开两个终端,分别运行两个程序,你会得到如下的结果。
python学习心得之:socket实现终端对话

三、计算机间通讯

 
  我不知道各位有没有留意到我刚才一直提到“在同一台电脑上”,事实上,若是你使用上面的代码,在不同的计算机上运行,必然是会报错的,那是因为,我们的服务器和客户端的host都是socket.gethostname(),这句代码是用来获取本机的hostname的,很显然,如果你想实现两台设备之间的通讯,则必须把客户端的host改为服务器端的host。

四、结论

 
  到了这里,其实相信各位也看明白了,python搭建简易的服务器其实完全可以套路化

#服务器端
import socket
s = socket.socket()
host = socket.gethostname()
port = 9000 
s.bind((host, port))
s.listen(5)
c, addr = s.accept()
#you code here

#客户端
import socket
s = socket.socket() 
host = "服务器host"
port = "服务器port"
s.connect((host, port)) 
#you code here
s.close()

 
  你只需要将你希望计算机做出的反应填写在#you code here处即可

五、Demo

 
  说了这么多,下面附上我做的一个小demo

#服务器端
import socket
s = socket.socket()
host = socket.gethostname()
port = 8000
s.bind((host, port))

s.listen(5)
while True:
    print("="*100)
    print('等待用户连接……')
    c, addr = s.accept()
    print('用户已连接 address:{}\n{}\n服务器:请问需要什么帮助'.format(addr,"-"*50))
    c.send(bytes("请问需要什么帮助?输入quit结束对话",encoding="utf-8"))
    while True:
        mes = str(c.recv(1024),encoding = "utf-8")
        print("客户端:{}".format(mes))
        if mes == "quit":
            c.send(bytes("再见",encoding="utf-8"))
            break
        mes = input("服务器:")
        c.send(bytes(mes,encoding="utf-8"))
    c.close()

#客户端
import socket
s = socket.socket()
host = socket.gethostname()
port = 8000
s.connect((host, port))
while True:
    mes = str(s.recv(1024),encoding = "utf-8")
    print("服务器:{}".format(mes))
    if mes == "再见":
        break
    mes = input("客户端:")
    s.send(bytes(mes,encoding="utf-8"))
s.close()

 
  实现效果如下图:
python学习心得之:socket实现终端对话

六、总结

本文详细介绍了python搭建简易服务器的过程,然而技术是复杂的,下面总结一些问题,留待以后学习解决:
  1.本文中服务器最大监听数量为5,后连接的客户端需要等待,然而我尝试修改该数字为1,仍然可以继续等待
  2.如何使拂去其向等待的客户端发送等待通知
  3.本文中服务器与客户端交替进行交流对话,如若乙方连续发送,则会出现一定的混乱,如何解决?
  
  以上就是本文的全部内容,欢迎各位一同交流学习。