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

如果有誰有更好的免費穩定的聊天服務器,也歡迎留言共享

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章