python3 socket编程学习实例:一个简易C/S模型

  • 服务端:
    监听来自客户端的消息,收到消息后记录到日志并回复给客户端一条消息
#!/usr/bin/env python3
# encoding:utf-8
#
#   SERVER
#

import socket
from socket import *
import os

HOST = '192.168.1.88'
PORT = 55555

#只接收这么多个bytes
BUFFERSIZE = 1024

# socket实例,UDP连接 
s = socket(AF_INET, SOCK_DGRAM)
# 重用ip和端口
s.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
# s绑定主机地址和端口
s.bind((HOST, PORT))
# 监听队列
#s.listen()
# 服务器对话日志
logfile = 'dialog.log'

def server_print(*msg):
    # TODO: 这里格式还是不好,应该支持带格式的字符串
    print("SERVER: ", msg)

def clean_up():
    if os.path.exists(logfile):
        os.remove(logfile)

clean_up()

# 简单地监听客户端的消息,收到消息后回复确认
while True:
    print("=== THE SERVER START WORKING ===")
   # 此处的s.recvfrom方法和s.recv都会返回接收到的数据,而recvfrom还会返回客户端的地址
    data, addr = s.recvfrom(BUFFERSIZE)
    data = data.decode(encoding='utf-8')
    server_print("recived message from client(%s): %s" % (addr, data))
    with open(logfile, 'a') as f:
        log = "client{0} \t message: {1}\n".format(addr, data)
        f.write(log)

   # 回复消息
    s.sendto("SERVER ROGER THAT ".encode(encoding='utf-8'), addr)

if not s._closed():
s.close()

# TODO: 
# 不知道怎么退出服务端好 ...
# 如果通过客户端输入`exit`来退出,则会导致客户端英文和服务端断开连接而异常退出
# 然后如果在服务端加入input和用户交互,则会导致客户端和服务端必须依次轮流发送信息 ...
  • 客户端
    1. 在任意和服务端同网络的主机上运行
    2. 向服务端发送消息
    3. 输入exit退出客户端

#!/usr/bin/env python3
#   encoding:utf-8
#   CLIENT

import sys
import socket
from socket import *

HOST = '192.168.1.88'
PORT = 55555
addr = (HOST, PORT)

#一次接收这么多bytes
BUFFERSIZE = 1024

# SOCK_DGRAM :UDP连接
s = socket(AF_INET, SOCK_DGRAM)
# socket类s去连接服务器
s.connect((HOST, PORT))

def client_print(*msg):
    print("CLIENT: ", msg)

while True:
    kel = input('Question >>')
    if kel == 'exit':
        break

    client_print('input data: %s' % kel)
    # python3 socket 只能收发二进制数据,需要转码
    kel = kel.encode(encoding='utf-8')
    #s.sendall(kel)
    # 发送数据
    try:
        s.sendto(kel, addr)
        # 接收数据
        data, addr = s.recvfrom(BUFFERSIZE)
        client_print("recived message from server({0}:{1}) : {2}".format(addr[0], addr[1], data.decode('utf-8')))
    except ConnectionRefusedError:
        client_print("exit client")
        s.close()

if not s._closed:
    s.close()

sys.exit()

  • 主要就是利用select.select来监控客户端本地输入和服务端的socket输入
  • 客户端可以复用
  • 只要修改HOST和PORT即可运行


  • 再另外又尝试了MySQL相关模块pymysql的使用,来实现客户端用户的注册和登录功能:

/usr/bin/python3.5 /home/czh/PycharmProjects/socket-cs-chatroom/chat-room/chat-client1.py
[登录]输入你的名字:czh
[登录]您的账户不存在!
[登录]您的账户不存在!
[登录]是否注册?(y/n)y
[注册]输入你的名字:czh
用户名最少6个字符!
[注册]输入你的名字:czh123
[注册]输入你的密码:123123
[注册]name: czh123, passwd: e1073014259484c3c6dfd52196f22545, times: 2018-06-22
Registered succeed!
[登录]输入你的名字:czh123
[登录]输入你的密码:123123
登录成功!czh123,欢迎您。
connection succeed!
exit
>> exit

猜你喜欢

转载自blog.csdn.net/u013390088/article/details/80452817
今日推荐