通过python的socket库实现简易即时通讯小程序

前言

  最近学习了一下有关tcp协议和socket有关的知识,看到许多socket实战都喜欢教如何做一个聊天程序,于是想着试试能不能不看教程自己写一个。当然我没太多时间做一个像qq一样的ui界面,所以做了个命令行程序。

  下面是我写好的代码:

server代码

import socket
import threading

serveraddr = ('0.0.0.0', 8080)#定义server的ip和地址

class Server:#server类
    def __init__(self):
        self.user={}
        self.addr={}
        self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        self.server.bind(serveraddr)
        self.server.listen(128)

    def add_user(self,name,addr):
        self.user[name]=addr
        self.addr[addr[0]+str(addr[1])]=name

    def get_user(self,name):
        return self.user[name]

def main_thread(server,client,address):#主线程函数
    datalist = client.recv(1024).decode('utf-8').split(' ', 3)
    if datalist[1] == 'login':#登录
        server.add_user(datalist[2],address)
        client.send(str(address[1]).encode('utf-8'))
        print('用户'+datalist[2]+'已录入',server.user[datalist[2]])
    elif (datalist[1] == 'send' and len(datalist) == 4):#发送
        if(datalist[2] in server.user.keys()):
            target = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
            target.connect(server.get_user(datalist[2]))
            target.send(('用户'+datalist[0]+'发来一条信息:'+datalist[3]).encode('utf-8'))
            client.send('success'.encode('utf-8'))
            print('用户'+datalist[0]+'给用户'+datalist[2]+'发送了一条信息:'+datalist[3])
            target.close()
        else:
            client.send(('用户'+datalist[2]+'不存在').encode('utf-8'))
            print('用户'+datalist[2]+'不存在')
    elif datalist[1] == 'close':#退出
        print('已删除用户'+datalist[0])
        client.send('success'.encode('utf-8'))
        del server.user[datalist[0]]
    else:#其他
        client.send('格式有误'.encode('utf-8'))
    client.close()

def server_thread(server):#服务端
    print('服务器已开启')
    while(True):
        client, address = server.server.accept()
        threading.Thread(target=main_thread, args=(server,client,address)).start()

if __name__ == "__main__":
    server = Server()
    threading.Thread(target=server_thread, args=(server,)).start()
    while(True):
        put = input()
        if(put=='close'):
            server.close()
            break
        else:
            print('无效指令')

client代码

import socket
import threading

serveraddr = ('127.0.0.1', 8080)#定义server的ip和地址

def client_thread(client,port):#客户端
    client.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    client.bind(('127.0.0.1', port))
    client.listen(1)
    while(True):
        clientsocket, address = client.accept()
        print(clientsocket.recv(1024).decode('utf-8'))

if __name__ == "__main__":
    #login指令
    target = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    target.connect(serveraddr)
    id = input('请输入你的用户名: ')
    target.send(('none login '+id).encode('utf-8'))
    port = int(target.recv(1024).decode('utf-8'))
    print('链接成功')
    target.close()
    #启动客户端
    client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    threading.Thread(target=client_thread, args=(client,port)).start()
    #开始发送指令
    while(True):
        put = id+' '+input()
        target = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        target.connect(serveraddr)
        target.send(put.encode('utf-8'))
        callback = target.recv(1024).decode('utf-8')
        if(callback!='success'):
            print(callback)
        target.close()
        if put.split(' ')[1] == 'close':#关闭客户端
            break
    client.close()

运行效果

 

  client有三种命令,login,send,close,login只有且必须在client刚开启时使用,send就是发消息指令,close就是退出指令。

  server只有close指令,用来停止server。

  因为手上没有服务器的缘故只能在本机上完成,无法测试不同主机的效果,不过理论上应该可以(别打脸)。只需要把python文件的ip地址和端口改下就行,server放到云服务器开启,client在主机上使用,就可以模拟出简单的即时通讯了。

  

  GitHub地址:https://github.com/modifyGB/mysocket

posted @ 2020-08-30 01:44  Epitaph  阅读(749)  评论(1编辑  收藏  举报