python实现的广域网聊天(无需搭建服务器,基于FICS和socket模块)

FICS是免费的国际象棋服务器(其实就是个命令行下棋的网站,有许多界面比如BabasChess、Arena、iNemesis或者我们的Verachess支持访问),里面允许未注册会员登录,而且他们登录以后也可以聊天。所以我就利用这一点,实现在广域网借FICS的服务器来聊天。(虽然延迟有点大,而且每次聊天的字数有限制,每一句只能有十几个汉字)

这里真正的困难点在于,FICS客户端不支持中文字符的聊天,我开始使用.encode(‘string-escape’)和.decode(‘string-escape’),然而中文太占地方,一共一句话就限制54个字符,一个中文要8个(可以压缩为6个)字符,也就是一句话最多只能9个汉字。后来我就改用base64编码了,测算可以支持20个左右汉字。因为FICS的网络延迟有点大,我没有做超长文本的分片功能,如果有谁有兴趣可以改进。

# coding: gbk
# must run in CMD, pycharm has a bug when input interrupted
import socket, threading, sys, re, time, base64
client=socket.socket()
print '连接服务器中,请稍候'
try:
    client.connect(('freechess.org',5000))
except:
    print '服务器连接超时'
    sys.exit(-1)
chatting=False

def startwith(instr,totalstr):
    totalstr=totalstr.replace('\r','')
    return totalstr[:len(instr)]==instr

def blockData(chan):
    '''
    :param socket._socketobject chan:
    :return:
    '''
    global chatting
    buffer=''
    while True:
        data=chan.recv(1)
        if data:
            buffer+=data
            if startwith('login:', buffer):
                chan.send('guest\n')
                buffer=''
            elif buffer[-1]=='\n':
                if startwith('Press return to enter the server as ',buffer):
                    chan.send('\n')
                    print '您的昵称是:'+re.findall('"Guest(.*)"',buffer)[0]
                    print '输入对方的昵称+消息(中间以空格隔开),即可发送聊天信息,输入quit则退出登录'
                    chatting=True
                elif startwith('Thank you for using the Free Internet Chess server ',buffer):
                    print '您已经退出登录'
                elif '(told ' in buffer:
                    print buffer[:-1].replace('\r','').replace('told','消息已发送给').replace('fics% ','')
                elif 'is not logged in.' in buffer:
                    print buffer[:-1].replace('\r','').replace('is not logged in','不在线').replace('fics% ','')
                elif '(U) tells you: ' in buffer:
                    try:
                        buffer=buffer.replace('\r','')  # 万一用户乱输入,可能杯具。我们之前压缩过中文,解压一下
                        i=buffer.index('(U) tells you:')
                        left=buffer[:i]+' 对你说: '
                        right=base64.b64decode(buffer[i+15:])
                        print left+right
                    except:
                        print buffer.replace('\r','').replace('(U) tells you:', ' 对你说:')
                buffer=''
        else:
            print '连接关闭成功'
            chatting=False
            break
b=threading.Thread(target=blockData,args=(client,))
b.setDaemon(True)
b.start()
s=0
while s<150 and not chatting:
    time.sleep(0.1)
    s=s+1
if not chatting:
    print '服务器响应超时'
    sys.exit(-1)

while chatting:
    ui=raw_input('')
    if ui=='quit':
        client.send('quit\n')
        s=0
        while chatting and s<50:
            time.sleep(0.1)
            s=s+1
        sys.exit(0)
    elif chatting:
        try:
            assert len(ui.split(' '))>=2
            assert len(ui.split(' ')[0])==4
            assert len(ui)>5
        except:
            print '输入的信息格式不正确,请重新输入'
        else:
            try:
                ui=ui[:5]+base64.b64encode(ui[5:])  # 使用base64压缩
                assert len(ui)<60
            except:
                print '输入信息超长,请重新输入'
            else:
                client.send(('tell Guest%s\n'%ui))  # fics不支持中文,我们必须编码为utf-8字节码格式

将其使用py2exe 0.6.9(32位)打包,运行时却报MSVCR90.dll找不到的错误,且用VC++2008运行库修复无效。后来360软件管家发现VC++2008 x86的运行库重复安装了。把两个安装项都卸载,然后重装VC++2008,再重新打包(重要)后,终于成功。
运行效果如下:
在这里插入图片描述
这里提供demo的下载(client是裸FICS客户端,chat是基于client封装的聊天客户端,也就是图上这样)
链接:https://pan.baidu.com/s/1zeyAcbWuIhukxoEoVJtEBQ
提取码:v144

如果有谁有更好的免费稳定的聊天服务器,也欢迎留言共享

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值