在linux上编写socket服务端程序一般可以用select、poll、epoll三种方式,本文主要介绍使用select编写socket服务端模块与客户端模块。
服务器端程序代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
|
import
socket
import
select
import
Queue
server
=
(
'10.0.2.15'
,
21345
)
#SOCK_STREAM(流套接字)、SOCK_DGRAM(数据报文套接字)、AF_INET(IPv4)
sock
=
socket.socket(socket.AF_INET,socket.SOCK_STREAM)
#阻塞与端口复用前后顺序可换
sock.setblocking(
False
)
#SOL_SOCKET(套接字描述符)、SO_REUSEADDR(端口复用)
sock.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,
1
)
sock.bind(server)
sock.listen(
5
)
rlists
=
[sock]
wlists
=
[]
msg_que
=
{}
timeout
=
10
while
True
:
rs,ws,es
=
select.select(rlists,wlists,rlists,timeout)
if
not
(rs
or
ws
or
es):
print
'timeout...'
continue
#读部分
for
s
in
rs:
#看s是否是本机上用于监听的socket,是则接受连接,不是则接收数据
if
s
is
sock:
conn,addr
=
s.accept()
#conn、addr分别是所接收到的socket对象和对方端口
print
'connect by'
,addr
conn.setblocking(
False
)
rlists.append(conn)
#使用字典将conn与一个队列相对应
msg_que[conn]
=
Queue.Queue()
else
:
data
=
s.recv(
1024
)
if
data:
print
data
msg_que[s].put(data)
if
s
not
in
wlists:
wlists.append(s)
else
:
if
s
in
wlists:
wlists.remove(s)
rlists.remove(s)
s.close
del
msg_que[s]
#写部分
for
s
in
ws:
try
:
#get_nowait()跟get(0)一样
msg
=
msg_que[s].get_nowait()
except
Queue.Empty:
print
'msg empty'
wlists.remove(s)
else
:
s.send(msg)
#异常部分
for
s
in
es:
print
'except'
,s.getpeername()
if
s
in
rlists:
rlists.remove(s)
if
s
in
wlists:
wlists.remove(s)
s.close
del
msg_que[s]
|
客服端程序代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
# -*- coding: utf-8 -*-
#使用utf-8在命令行窗口里才能运行
import
socket
import
time
#getpeername()获得socket对方的地址
server
=
(
'10.0.2.15'
,
21345
)
msg
=
[
'hello'
,
'welcome'
,
'xiaoming'
,
'zhangsan'
,
'list'
,
'liuliu'
]
socks
=
[]
for
i
in
range
(
10
):
sock
=
socket.socket(socket.AF_INET,socket.SOCK_STREAM)
socks.append(sock)
for
s
in
socks:
s.connect(server)
counter
=
0
for
m
in
msg:
for
s
in
socks:
s.send(
'%d send %s'
%
(counter,m))
counter
=
counter
+
1
for
s
in
socks:
data
=
s.recv(
1024
)
print
'%s echo %s'
%
(s.getpeername(),data)
if
not
data:
s.close()
time.sleep(
2
)
|
可以在编译器中运行服务端程序,然后使用命令行方式运行客户端程序进行测试。