专栏首页工科生日常HoneyTalk——我和我女朋友的专属情侣聊天器

HoneyTalk——我和我女朋友的专属情侣聊天器

其实这并不是什么大不了的东西 就是想写点东西 练练手 骗骗人 顺带着唬一唬你们 说道这个聊天器 不知道你们还记不记得这个

特别烂的Arduino聊天器 聪明的瓦肯人,公众号:工业光线嘘~~听说有逼格的人都基于Arduino搭建个人聊天室了!

见过烂的 没见过这么烂的

当然 这本身就不是什么主流玩意儿 一些软件适配做的非常糟糕 也是在情理之中

Arduino聊天室是一个匿名群聊应用 但是今天的应用是一对一 专属情侣聊天 话不多说 还不快来看看

1 情侣聊天 最重要的是什么? 当然是隐私 隐私是什么 隐私就是隐藏在个人心中的私事 由此看来 今天我们在社交软件上说的 每一句话都掌握在第三方机构中 这还得了

so 我们急需重新定义个人聊天 尤其是情侣聊天 让人民群众掌握自己的信息 才是最大的幸福

所以 为了拯救人民于水深火热之中 今天我(们)重磅推出 C2C聊天应用 HoneyTalk (以下简称HT)

HoneyTalk分为 He和She 实际上 HT是伪C2C,真S2C 因为其中一端就是服务端 直接将服务端作为客户端的方式 绕过了第三方服务器 在最大程度上保护了隐私 所有数据只有对话双方知道 当然这种方式增加了联通的复杂性 这是因为以现状来看 如果你想要联通任何人 每人既需要服务端用来等待连接 也需要客户端发起连接 非常不方便 目前看来 只适合情侣聊天这种单一简单场景 我们先来看看界面

显而易见

这高贵的0.9透明度

彰显着年轻人的不拘一格 交互界面非常简单 其中蓝色界面是服务端界面 粉色界面是客户端界面

1区是对话显示区

2区是消息发送区 设计初衷一目了然 男生是服务端 女生是客户端

但不仅仅如此

你们一定以为

作为服务器的男生一定占据着主动

而女生则处处被动

确切的说

服务器是否运行确实决定了软件是否运行

但是

作为宠妻狂魔

我......呃呃呃

emmmm~

不对呀

嘴巴不受控制了

(不好意思,这是未来的事)

反正

我是不可能让我广大女朋友吃亏的

只要广大女朋友

能说服你的直男启动服务器

我小瓦就能帮你扳回一局

这是为什么呢?

这是因为我小瓦赋予了

客户端非常高的权限

什么意思?

首先

服务器一旦启动

男生没有发起对话的权利

这一点很好理解

服务器总是在等待连接

只有当你心爱的女朋友

开心了、伤心了、寂寞了

打开了HT发起连接

服务器才响应启动对话界面

可是很不幸

今天这个渣男非常不耐烦

企图关掉对话界面

嘿嘿嘿!

不好意思你没有这个权限

渣男不但没有权限

而且这个危险的行为

会立刻被你女朋友知晓

可是如果情况恰恰相反

你的女朋友今天看你不爽

难得理你

她只需轻轻地抬起她的玉指

就可以了结此次对话

所有对话界面都将关闭

可是你还想你侬我侬

怎么办?

不要急,办法总比困难多

这时候

你必须马上送上

兄弟

听我一句话

不在乎那点钱

保命要紧

2

介绍完了基本情况

再来点实在的

关于怎么用的问题

当你下载了文件后

首先你需要注意的是

由于程序需要调用.ico图标

所以你必须保证.ico图片与程序在同一目录下

然后

服务端很简单

双击HoneyTalkHe.exe

等待一段时间,显示基本信息

之后会隐藏在后台运行

要想关闭得去任务管理器进程界面

而客户端

双击HoneyTalkShe.exe

等待之后出现如下

你需要输入地址与端口

局域网下

你得去问问渣男地址

端口我已设好

只能是8888

公网下

渣男得去做socket内网穿透

地址与端口视情况而定

每一次填好后然后回车

最后等待连接

成功后就能快乐的私密的聊天了

最后

请不要重复启动

那样你将打开一个无用界面

3

送上代码是我一向的原则

本次练手小项目

结合了Socket网络编程与GUI编程

这其中有一些坑得亲自去踩才有意义

公众号发送“HT”获得软件

或者

github地址:https://github.com/xjc-jim/HoneyTalk

服务端:

#!/usr/bin/env python3
# 文件名:socket_fuWu.py
# 开发者:聪明的瓦肯人
# 微信公众号:工业光线
# 个人主页:http://www.tech-xjc.com

import socket
import time
import win32api
import win32gui
from tkinter import *
import threading
from tkinter import scrolledtext
from tkinter.messagebox import showerror
from tkinter.messagebox import showinfo

#回调函数事件
event = '<Return>'     
error = '注意:对面的渣男试图关闭对话框,已被拦截!'

# 创建 socket 对象
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)

#获取本机电脑名
myname = socket.gethostname()
#获取本机ip
myaddr = socket.gethostbyname(myname)

print(myname)
print(myaddr)
s.bind((myaddr,8888))

s.listen(1)
print("waiting......")
print('5秒后将隐藏窗口!')
time.sleep(5)

#隐藏控制台窗口
ct = win32api.GetConsoleTitle()
hd = win32gui.FindWindow(0,ct)
win32gui.ShowWindow(hd,0)                           
class GUI(object):
    def __init__(self,root):
        self.root = root
        self.root.geometry('270x360')
        self.root.resizable(width=False, height=False)
        self.root.title('HoneyTalk_HE')
        self.root.iconbitmap('boy.ico')
        self.root['background'] = 'lightskyblue'
        self.root.attributes('-alpha',0.9)
        # 检测关闭按钮
        self.root.protocol('WM_DELETE_WINDOW',self.close)
        self.entry = Entry(self.root)
        self.entry.place(x=10,y=325)
        # 检测回车
        self.entry.bind("<Return>",self.callback)
        self.button = Button(self.root,text = 'send',command = self.sending)
        self.button.place(x=165,y=322)
        self.button0 = Button(self.root,text = 'More',command = self.more)
        self.button0.place(x=215,y=322)
        self.sock = sock
        self.out = scrolledtext.ScrolledText(self.root)
        self.out.place(x=10,y=0,width=250)
        #设置tag即插入文字的大小,颜色等
        self.out.tag_config('tag0',foreground = 'hotpink') 
        self.out.tag_config('tag1',foreground = '#1E90FF')

    def close(self):
        try:
            showerror('警告','渣男好大的胆,你无权关闭对话框!')
            self.sock.send(error.encode('utf-8'))
        except:
            self.sock.send(error.encode('utf-8'))
            pass
        return
        
    def sending(self):
        content = self.entry.get()
        
        if content != '':
            self.out.config(state = 'normal')
        self.out.insert(END,'HE:'+content+'\n\n','tag1')
        self.out.see(END)
        self.out.config(state = 'disable')
        
        try:
            self.sock.send(content.encode('utf-8'))
            self.entry.delete(0,END)
        except:
            sock.shutdown(2)
            sock.close()
            pass

    #回调函数
    def callback(self,event):                   
        content = self.entry.get()
        
        if content != '':
            self.out.config(state = 'normal')
        self.out.insert(END,'HE:'+content+'\n\n','tag1')
        self.out.see(END)
        self.out.config(state = 'disable')
        
        try:
            self.sock.send(content.encode('utf-8'))
            self.entry.delete(0,END)
        except:
            pass

    def more(self):
        try:
            showinfo(title='关于',message='1.作者:聪明的瓦肯人 \n2.公众号:工业光线(GongYe_Light) \n3.个人主页:http://www.tech-xjc.com \n4.公众号发送“honeytalk”获得详细介绍 \n5.网络问题会造成回复延迟 \n6.正常使用时请勿重复启动 \n7.请先启动该服务器再启动客户端 \n')
        except:
            pass
    
def create():
    global gui
    global root
    root = Tk()
    gui = GUI(root)
    
def rec():
    while True:
        try:
            msg = sock.recv(1024)
            gui.out.config(state = 'normal')
            con = bytes.decode(msg)
            gui.out.insert(END,'SHE:'+con+'\n\n','tag0')
            gui.out.see(END)
            gui.out.config(state = 'disable')
        except:
            sock.shutdown(2)
            sock.close()
            break
    # 退出mainloop
    root.quit()
    

if __name__ == '__main__':
    while True:
        sock,addr = s.accept()

        t1 = threading.Thread(target = rec,name = 'rec')
        t1.setDaemon(True)
        
        create()
        t1.start()
        root.mainloop()
        # 彻底关掉界面
        root.destroy()

客户端:

#!/usr/bin/env python3
# 文件名:socket_keHu.py
# 作者:聪明的瓦肯人
# 微信公众号:工业光线
# 个人主页:http://www.tech-xjc.com

# 导入 socket 等模块
import os
import time
import socket
import sqlite3
import win32api
import win32gui
from tkinter import *
import threading
from tkinter import scrolledtext
from tkinter.messagebox import showinfo

adr = input('>>请输入局域网或公网地址:')
port = input('>>请输入局域网或公网端口:')
#回调函数事件
event = '<Return>'  
error = '注意:对面的渣男试图关闭对话框,已被拦截!'

# 创建 socket 对象
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 

# 连接服务,指定主机和端口
try:
    s.connect((adr, int(port)))
    print('连接成功!')
    print('5秒后隐藏窗口!')
    time.sleep(5)
    
    #隐藏控制台窗口
    ct = win32api.GetConsoleTitle()
    hd = win32gui.FindWindow(0,ct)
    win32gui.ShowWindow(hd,0)   
except:
    print('连接失败,地址端口错误或服务器未启动!')
    print('5秒后关闭程序')
    time.sleep(5)
    os._exit(0)

class GUI(object):
    def __init__(self,root):
        self.root = root
        self.root.geometry('270x360')
        self.root.resizable(width=False, height=False)
        self.root.title('HoneyTalk_SHE')
        self.root.iconbitmap('girl.ico')
        self.root['background'] = 'pink'
        self.root.attributes('-alpha',0.9)
        self.root.protocol('WM_DELETE_WINDOW',self.close)
        self.entry = Entry(self.root)
        self.entry.place(x=10,y=325)
        self.entry.bind("<Return>",self.callback)
        self.button = Button(self.root,text = 'Send',command = self.send)
        self.button.place(x=165,y=322)
        self.button0 = Button(self.root,text = 'More',command = self.more)
        self.button0.place(x=215,y=322)
        self.out = scrolledtext.ScrolledText(self.root)
        self.out.place(x=10,y=0,width=250)
        #设置tag即插入文字的大小,颜色等
        self.out.tag_config('tag0',foreground = 'hotpink') 
        self.out.tag_config('tag1',foreground = '#1E90FF')

    def close(self):
        #showinfo('提示','确认关闭程序吗?')
        s.close()
        os._exit(0)

    def send(self):
        content = self.entry.get()
        
        if content != '':
            self.out.config(state = 'normal')
        self.out.insert(END,'SHE:'+content+'\n\n','tag0')
        self.out.see(END)
        self.out.config(state = 'disable')
        
        try:
            s.send(content.encode('utf-8'))
            self.entry.delete(0,END)
        except:
            pass

    def callback(self,event):
        content = self.entry.get()
        
        if content != '':
            self.out.config(state = 'normal')
        self.out.insert(END,'SHE:'+content+'\n\n','tag0')
        self.out.see(END)
        self.out.config(state = 'disable')
        
        try:
            s.send(content.encode('utf-8'))
            self.entry.delete(0,END)
        except:
            pass

    def more(self):
        showinfo(title='关于',message='1.作者:聪明的瓦肯人 \n2.公众号:工业光线(GongYe_Light) \n3.个人主页:http://www.tech-xjc.com \n4.公众号发送“honeytalk”获得详细介绍 \n5.网络问题会造成回复延迟 \n6.正常使用时请勿重复启动 \n7.请先启动服务器再启动该客户端 \n')
    
def create():
    global gui
    global root
    root = Tk()
    gui = GUI(root)
    root.mainloop()

def rec():
    while True:
        try:
            msg = s.recv(1024)
            gui.out.config(state = 'normal')
            con = msg.decode('utf-8')
            
            if con == error:
                gui.out.insert(END,con+'\n\n')
            else:
                gui.out.insert(END,'HE:'+con+'\n\n','tag1')

            gui.out.see(END)
            gui.out.config(state = 'disable')
        except:
            gui.out.config(state = 'normal')
            gui.out.insert(END,'啊哦~!服务器疑似下线!请敦促男友重启!然后再重启客户端!\n\n')
            gui.out.see(END)
            gui.out.config(state = 'disable')
            break

if __name__ == '__main__':
    t1 = threading.Thread(target = create,name = 'create')
    t1.start()
    try:
        rec()
    except:
        pass

over!

本文分享自微信公众号 - 工科生日常(ES-Daily),作者:聪明的瓦肯人

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-12-23

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 如何用python写一个安卓APP?(上)

    1 针对这个问题 我劝大伙儿谨慎尝试 谨慎尝试 为什么咧 我把大家骗进来的目的 就是让大家看看 什么叫做 好惨一男的 不过放心 你依然可以看到 这个问题的 可能...

    聪明的瓦肯人
  • 基于人体红外热释电检测的树莓派邮件报警器

    只要标题够唬人,你们就会点进来,内容什么的其实都无所谓,无聊已经逼迫帅气的我做出了这种东西?!

    聪明的瓦肯人
  • 编写HoneyTalk遇到的那些坑

    除此之外 一定要注意 tkinter GUI程序与线程的关系 你可能觉得这有什么好注意的 这是由于如果你将GUI现在了非主线程中 会出现错误 RuntimeE...

    聪明的瓦肯人
  • Python用list实现堆栈和队列

    利用数组 Q[1..n] 来实现含有 n-1 个元素队列(保留一位元素用来判断队列空或满)。该列有一个属性 Q.head 指向队头元素,属性 Q.tail 指向...

    马修
  • 【CV中的Attention机制】ECCV 2018 Convolutional Block Attention Module

    这是【CV中的Attention机制】系列的第三篇文章。目前cv领域借鉴了nlp领域的attention机制以后生产出了很多有用的基于attention机制的论...

    BBuf
  • 中文NLP笔记:11. 基于 LSTM 生成古诗

      在每行末尾加上 ] 符号是为了标识这首诗已经结束,说明 ] 符号之前的语句和之后的语句是没有关联关系的,后面会舍弃掉包含 ] 符号的训练数据。

    杨熹
  • python笔记:随机数,md5,en/decoder

    超级大猪
  • AlphaGo Zero你也来造一只,PyTorch实现五脏俱全| 附代码

    遥想当年,AlphaGo的Master版本,在完胜柯洁九段之后不久,就被后辈AlphaGo Zero (简称狗零) 击溃了。

    量子位
  • 测试面试 | Python 算法与数据结构面试题系列二(附答案)

    ⬆️ 关注 @霍格沃兹测试学院 公众号,回复「面试」,领取 BAT 大厂测试面试真题专辑。

    霍格沃兹测试开发
  • python设计模式-建造者模式

    Pizza 的制作流程包括:准备(擀面皮、加佐料),然后烘烤、切片、装盒。这些有特定的顺序,不能错乱。

    goodspeed

扫码关注云+社区

领取腾讯云代金券