Python socket 编程入门

本文介绍了Python中使用socket进行TCP/IP通信的基础知识,包括socket的定义、创建客户端和服务端的步骤,以及测试程序的运行结果。通过实例展示了如何实现客户端发送名字信息,服务端回应欢迎信息的功能,并强调了socket对象在编程中的重要性。
摘要由CSDN通过智能技术生成

什么是 socket?

可以简单地认为,socket 就是操作系统对于 TCP 连接的封装。通过 socket,我们可以进行简单可靠的网络传输。

目标

我们打算编写这么一个简单的程序:

  1. 客户端与服务端建立连接,端口为6666。
  2. 服务端发送信息,询问名字。
  3. 客户端发送名字信息。
  4. 服务端发送欢迎信息。
  5. 断开连接,客户端退出。

编写客户端

客户端的代码比较简单。

client.py

import socket

# AF_INET是Address Family: Internet的缩写,如果你要使用IPv6,就传入socket.AF_INET6
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(('127.0.0.1', 6666))
# 一次只接受1kb的数据,这个值是比较合理的
b = sock.recv(1024)
# 注意,网络传输的数据都是bytes类型
print(b.decode('utf-8'))
name = input('')
sock.send(name.encode('utf-8'))
b = sock.recv(1024)
print(b.decode('utf-8'))
sock.close()

要进行 socket 编程,首先要初始化一个 socket 对象,如果你要用 IPv4 进行通信,就传入 socket.AF_INET 和 socket.SOCK_STREAM,这是最常用的配置。接着,我们用 connect 方法连接上服务端,然后用 recv 和 send 方法进行数据的往来。最后一定要记得用 close 方法关闭 socket。

编写服务端

服务端的代码稍微复杂一些,要用到多线程。

server.py

import socket
import threading

def processLink(sock):
    sock.send(b"What's your name?")
    r = sock.recv(1024)
    greeting = b'Hello, ' + r + b'!'
    sock.send(greeting)
    sock.close()

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(('127.0.0.1', 6666))
# 5表示正在“排队”的连接个数最多是5,由于我们这个示例程序比较简单,
# 所以基本上不可能出现处理不过来排队的现象,因而这个值不太重要,5是最常见的取值
sock.listen(5)
while True:
    (s, addr) = sock.accept()
    thread = threading.Thread(target=processLink, args=(s,))
    thread.start()

与客户端不同,服务端要调用 bind 方法绑定端口,然后用 listen 方法开始监听。接着我们用一个无限循环来等待连接,如果有客户端连进来,accpet 方法就会返回一个 tuple,包含客户端的 socket 和网络地址,然后我们创建一个新的线程来处理这个连接。如果不用多线程,那么一次只能同时处理一个连接了!

测试程序

编写完之后,我们首先打开 server.py,然后打开 client.py,就会看到以下结果:

总结

socket 编程就是围绕着 socket 对象的,我们一般用 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 来初始化一个 socket 对象。

下面的表格列举了 socket 对象的常用方法。

通用

方法名称参数说明作用
s.recv(size)size:最多接受的字节数接受信息
s.send(data)data:要发送的数据发送信息,返回发送成功的字节数,也就是说,不一定能全部发送
s.sendall(data)data:要发送的数据发送信息,尽量保证全部发送,如果做不到,抛出一个异常
s.settimeout(timeout)timeout:操作阻塞的最大时间如果 timeout 是 None,表示无限阻塞,如果是 0,表示不阻塞,如果是非零的值,超过该时间(单位:秒)后会抛出 socket.timeout 异常
s.close() 关闭 socket

客户端

方法名称参数说明作用
s.connect(addr)addr:一个 tuple,第一个元素是 IP 地址,第二个元素是端口连接服务端

服务端

方法名称参数作用作用
sock.bind(addr)addr:一个 tuple,第一个元素是 IP 地址,第二个元素是端口绑定到要监听的端口
sock.listen(max)max:排队(未处理)的连接数的最大值开始监听
sock.accept() 与客户端建立连接,返回值是一个 tuple,第一个元素是客户端的 socket,第二个元素是客户端的地址

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值