服务端:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import socket
import sys
sk=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
sk.bind(('127.0.0.1',8080))
sk.listen(5)

while True:              #让服务端不停接受客户端
    print("开始接受请求!")
    conn,addr=sk.accept()       
    while True:
        try:             #这里是为了防止当某一个客户端断开后的异常导致服务端停止
            msg=conn.recv(1024).decode()
            if msg == "exit":
               sys.exit("进程通讯结束!")
            conn.sendall("服务器端已收到消息!".encode())
            print("来自%s向你发送了:%s" %(addr,msg))
        except Exception:
            break
    conn.close()

客户端1:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import socket
sk=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
sk.connect(('127.0.0.1',8080))
while True:
    inp=input("请输入要发送给服务端的消息:")
    if not inp:
        continue
    if inp == "exit":
        break
    sk.sendall(inp.encode())
    print("数据已发送成功等待返回数据")
    msg=sk.recv(1024).decode()
    print(msg)

sk.close()

客户端2:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import socket
sk=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
sk.connect(('127.0.0.1',8080))
while True:
    inp=input("请输入要发送给服务端的消息:")
    if not inp:
        continue
    if inp == "exit":
        break
    sk.sendall(inp.encode())
    print("数据已发送成功等待返回数据")
    msg=sk.recv(1024).decode()
    print(msg)

sk.close()

注释:我们在最前面学习了单客户端方式,但有一个问题当客服端断开的时服务端也会被断开,但这不是我们想要的效果,我们希望的服务是希望多客服端和不间断服务,不能因为一个客服端断开就停止服务。所以我们修改一下服务端,让服务端不停的接受客户端连接。这个时候当两个客户端一起发消息的时候只有一个客服端能得到服务端返回数据,另外一个客户端则需要等待第一个客户端连接断开后才能收到服务端的返回值。

-

注意:在mac上当客服端断开以后会一直接收为“空” 可以加上 if not msg:break

socket编程之多客服端(简易版)_第1张图片

socket编程之多客服端(简易版)_第2张图片

socket编程之多客服端(简易版)_第3张图片

在重启服务端时可能会遇到:

socket编程之多客服端(简易版)

解决方法1:加入一条socket配置,重用ip和端口
phone=socket(AF_INET,SOCK_STREAM)
phone.setsockopt(SOL_SOCKET,SO_REUSEADDR,1) #就是它,在bind前加
phone.bind(('127.0.0.1',8080))
发现系统存在大量TIME_WAIT状态的连接,通过调整linux内核参数解决,
vi /etc/sysctl.conf

编辑文件,加入以下内容:
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_fin_timeout = 30

然后执行 /sbin/sysctl -p 让参数生效。

net.ipv4.tcp_syncookies = 1 表示开启SYN Cookies。当出现SYN等待队列溢出时,启用cookies来处理,可防范少量SYN***,默认为0,表示关闭;

net.ipv4.tcp_tw_reuse = 1 表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭;

net.ipv4.tcp_tw_recycle = 1 表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭。

net.ipv4.tcp_fin_timeout 修改系統默认的 TIMEOUT 时间