前言

    今天学习了一些Python Socket的知识,现在把它记录下来.

1.socket简介

    套接字(socket)是一个抽象层,应用程序可以通过它发送或接收数据,可对其进行像对文件一样的打开、读写和关闭等操作。套接字允许应用程序将I/O插入到网络中,并与网络中的其他应用程序进行通信。网络套接字是IP地址与端口的组合。

注:这些概念我也不是很理解.我对socket的理解是:socket可以实现服务端与客户端之间的通信.

2.python实现一个简单的socket网络通信

服务端 socket_server.py

import socket

server = socket.socket()            # 声明socket类型,同时生成socket链接对象

server.bind(('localhost',6968))     # 绑定要监听的端口

server.listen(5)                     # 开始监听端口

print('开始监听:')
conn,addr = server.accept()                     # 等待客户端发送消息
print(conn)
print(addr)
print('监听到消息')

data = conn.recv(1024)            # 接收客户端发来的消息
print('server recv:',data)

conn.send(data.upper())           # 将客户端发来的消息进行大写并返回给客户

server.close()                      # 关闭

客户端 socket_client.py

import socket

client = socket.socket()                # 声明socket类型,同时生成socket链接对象
client.connect(('localhost',6968))      # 连接本地的6969端口

client.send(b"hello world!")             # 向服务端发送消息

data = client.recv(1024)                # 接收服务端发回来的消息
print('client recv:',data)

client.close()                          # 关闭客户端

注:这里只是实现了一个最简单的服务端与客户端的通信,只能完成"一来一回".

代码解释:

(1) 服务端:

    服务端要做的事情就是监听客户端的访问端口,然后接收客户端的访问信息,并将相关信息返回给客户端.
    第一步,创建socket对象,声明socket类型

import socket
server = socket.socket()            # 声明socket类型,同时生成socket链接对象

    第二步,将socket绑定到指定地址.socket.bind()方法是绑定端口,这里只接收一个参数,所以要传入一个元组.

server.bind(('localhost',6968))     # 绑定要监听的端口

    第三步,开始监听端口.注:server.listen()方法会接收一个参数,意思是最大监听数.

server.listen(5)                     # 开始监听端口

    第四步,等待客户端发送消息.运行accept()方法后,socket进入等待状态,等待客户请求连接.当用户请求连接时,accept()建立连接,返回两个值conn和addr.其中conn是新的socket对象,服务器要通过这个新的socket对象与客户端进行通信,addr是客户端的internet地址.

conn,addr = server.accept()                     # 等待客户端发送消息

    第五步,接收客户端发来的消息,这里要使用新的socket对象conn来与客户进行交流.

data = conn.recv(1024)            # 接收客户端发来的消息

    第六步,向客户端发送消息.这里只是将客户端发来的消息变成大写返回给客户端.

conn.send(data.upper())           # 将客户端发来的消息进行大写并返回给客户

    第七步,关闭服务端.

server.close()				# 关闭服务端
(2)客户端

    客户端做的事情就是访问服务端,并向服务端出入数据,同时接收服务端返回的数据.
    第一步,创建socket对象.声明socket类型

import socket
client = socket.socket()                # 声明socket类型,同时生成socket链接对象

    第二步,连接服务端

client.connect(('localhost',6968))      # 连接本地的6969端口

    第三步,向服务端发送消息

client.send(b"hello world!")             # 向服务端发送消息

    第四步,接收服务端发送来的消息

data = client.recv(1024)                # 接收服务端发回来的消息

    第五步,关闭客户端

client.close()							# 关闭客户端
运行结果:

打开两个终端,一个运行服务端,一个运行客户端,一个运行服务端.

注:我的运行环境为ubuntu16.04,python3.5.2

服务端展示–python socket_server.py

python 通常每个套接字地址只能用一次 python 本地套接字_服务端


客户端展示–python socket_client.py

python 通常每个套接字地址只能用一次 python 本地套接字_发送消息_02

注:这里只是实现了一个非常简单的类似于"一问一答"形式的socket通信,显然这不符合我们的习惯,接下来就实现一个服务端可以一直监听客户端访问,并且客户端也可以一直和服务端进行通信.

3.python socket通信改进

服务端 socket_server_2.py

'''
    服务端
'''
import socket

server = socket.socket()            # 创建socket对象,声明socket类型
print('server = ',server)

server.bind(('localhost',6600))     # 绑定要监听的地址和端口

print('开始监听端口:')
server.listen(5)                    # 最多允许挂起5个链接

'''
    内层循环的作用:与一个客户进行交流,当这个客户断开时,就回到外循环
    外循环的作用:外循环一直在监听客户端的访问,当一个客户端断开后,就监听新的客户端的访问
    这样就可以实现当一个客户端关闭时,另一个客户端就可以进行访问
    但是还不能实现多个客户端同时访问
'''
while True:
    conn, addr = server.accept()
    print('客户端连接成功')
    print('conn = {},addr = {}'.format(conn,addr))

    while True:
        data = conn.recv(1024)

        print('服务端接收的数据为: ',data.decode())

        if not data:
            print('客户端已关闭')
            break           # 注:这个break只是跳出了内层循环

        conn.send(data.upper())

server.close()

客户端 socket_client_2.py

'''
    客户端
'''
import socket

client = socket.socket()        # 创建Socket对象,声明socket类型

client.connect(('localhost',6600))
while True:
    msg = input("请输入: ")

    if len(msg) == 0:
        continue

    client.send(msg.encode('utf-8'))

    data = client.recv(1024)
    print('客户端接收的数据为: ',data.decode())


client.close()

代码解释:

(1) 服务端:

    服务端采用两个while循环,内层循环的作用是与一个客户进行交流,当这个客户断开时,就回到外循环,继续监听其他客户端的访问,外层循环的作用是一直监听客户端的访问,当一个客户端断开时,就监听其他的客户端的访问.

(2) 客户端:

    客户端就是采用了一个while循环来实现.

运行结果:

服务端–python socket_server_2.py

python 通常每个套接字地址只能用一次 python 本地套接字_服务端_03

服务端–python socket_client_2.py

python 通常每个套接字地址只能用一次 python 本地套接字_python_04

写在最后:

    这些内容只是我自己的见解,不到之处请多多批评指正.内容如有侵权,请及时联系我,感谢大家!