python中的socket网络编程(二)

1、前言

在python中的socket网络编程(一)一文中,我们介绍了客户端的主要功能。下面我们看下服务端。

2、具体实现

创建socket:

首先要创建 socket,用 Python 中 socket 模块的函数 socket 就可以完成:

#-*- coding: utf-8 -*-
import socket
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
print 'socket Created'

函数 socket.socket 创建一个 socket,返回该 socket 的描述符,将在后面相关函数中使用。该函数带有两个参数如下:

  • Address Family:可以选择 AF_INET(用于 Internet 进程间通信) 或者 AF_UNIX(用于同一台机器进程间通信)
  • Type:套接字类型,可以是 SOCKET_STREAM(流式套接字,主要用于 TCP 协议)或者SOCKET_DGRAM(数据报套接字,主要用于 UDP 协议)

绑定socket:

函数 bind 可以用来将 socket 绑定到特定的地址和端口上,它需要一个 sockaddr_in 结构作为参数。

# -*- coding: utf-8 -*-
import socket
import sys

sys
HOST = ‘’
PORT = 8888

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print 'Socket created'

try:
	s.bind((HOST, PORT))
except socket.error , msg:
	print 'Bind failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1]
	sys.exit()
 
print 'Socket bind complete'

监听连接:

函数 listen 可以将 socket 置于监听模式。

s.listen(10)
print 'Socket now listening'

该函数带有一个参数称为 backlog,用来控制连接的个数。如果设为 10,那么有 10 个连接正在等待处理,此时第 11 个请求过来时将会被拒绝。

接收连接,当有客户端向服务器发送连接请求时,服务器会接收连接。

conn, addr = s.accept()
print 'Connected with ' + addr[0] + ':' + str(addr[1])

为了处理每个连接,我们需要将处理的程序与主程序的接收连接分开。一种方法可以使用线程来实现,主服务程序接收连接,创建一个线程来处理该连接的通信,然后服务器回到接收其他连接的逻辑上来。完整的服务端代码如下:

import socket
import sys
from thread import *

HOST = ''   
PORT = 8888 

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print 'Socket created'

try:
	s.bind((HOST, PORT))
except socket.error , msg:
	print 'Bind failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1]
	sys.exit()    
print 'Socket bind complete'

s.listen(10)
print 'Socket now listening'

def clientthread(conn):
	conn.send('Welcome to the server. Type something and hit enter\n') 
	while True:
    	data = conn.recv(1024)
    	reply = 'OK...' + data
    	if not data: 
        	break     
    	conn.sendall(reply)     
	conn.close()

while 1:
	conn, addr = s.accept()
	print 'Connected with ' + addr[0] + ':' + str(addr[1])     
	start_new_thread(clientthread ,(conn,))

s.close()

在命令行下运行python server.py,服务端运行结果如下:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UsvK7srF-1593526582866)(http://odsh9s4s2.bkt.clouddn.com/server-socket.png)]

3、客户端测试

我们使用tcp/udp socket测试工具,模仿客户端。向服务端发送字符串,服务端接收字符串,然后返回。效果如下:
  [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-whygzbyK-1593526582869)(http://odsh9s4s2.bkt.clouddn.com/client-socket.png)]

4、总结

python网络编程服务端,我们需要经过如下五步:

  • 创建socket
  • 绑定到指定的地址及端口
  • 监听连接
  • 建立连接
  • 接收/发送数据
  • 关闭socket