关于搭建简易广域网私人通信程序(python)一步到位!

时间:2020-8-29 作者:admin


原料:python3,腾讯云服务器

用到的库:socket,sys,threading,time,pyinstaller。(除pyinstaller外均不需单独安装)

首先

默认已经买好云服务器,且安装好了python3,此处使用腾讯云服务器。WinSCP(传输文件)和putty(远程控制)是两个非常好用的与云服务器搭配使用的软件,均开源免费。

思路和目标

主要目标:打造一款简易的广域网通信程序。

  1. 不同局域网下两台电脑的用户可以聊天
  2. 用服务器做中转,服务器端主线程和新开线程共两个线程。
  3. 客户端也为主线程和新开线程,一个负责接收消息,一个负责发送消息。
  4. 本程序受此博客启发甚大,在此感谢!!TCP实现不同局域网通信

服务器端

# coding:utf-8
import socket
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
import threading
import time
HOST = ''   # Symbolic name meaning all available interfaces
PORT = 8888 # 随便设,但记得要安全组里打开,云服务器防火墙也打开此端口

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print ('Socket created')

#Bind socket to local host and port
try:
    s.bind((HOST, PORT))
except socket.error:
    print ('Bind failed. Error Code : ')
    sys.exit()

print ('Socket bind complete')

#Start listening on socket
s.listen(10)
print ('Socket now listening')
users=[]
#Function for handling connections. This will be used to create threads
def clientthread(sender,receiver,maxsize,num):
    print(num)
    sender.send(("WELCOME NO. "+str(num)+" USER").encode())
    while True:
        try:
            data=sender.recv(maxsize)
        except OSError:
            sender.send("无法获取发送内容".encode())
            time.sleep(2)
            print("无法获取发送内容")
            break
	except socket.error:
	    try:
		receiver.send("对方已离线,无法收到消息".encode())
	    except:
		print("离线发送失败")
	    print("socket erro in 无法发送")	
	    break
        if not data:
	    try:
            	receiver.send("对方已离线,无法收到消息".encode())
            except OSError:
		print("下线提示发送失败")
            except socket.error:
		print("offline failure")
        else:
            try:
                receiver.send(data)
            except OSError:
                sender.send("对方接收失败".encode())
                print("对方接收失败")
                break
            except socket.error:
		print("se on 接收失败")
		break

    

    

if __name__ == '__main__':
    #now keep talking with the client
    i=0
    while i<2:
        conn, addr = s.accept()#accept阻塞,意味着不接收到不会执行下边的代码
        conn.send("Wait...")
        users.append(conn)
        i+=1
    print ('Connected')
    #start new thread takes 1st argument as a function name to be run, second is the tuple of arguments to the function.
    threading._start_new_thread(clientthread ,(users[0],users[1],1024,0))
    clientthread(users[1],users[0],1024,1)
    s.close()

客户端

#coding:utf-8
import socket   #for sockets
import sys  #for exit
from time import ctime
import threading 
import time

try:
    #create an AF_INET, STREAM socket (TCP)
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except socket.error:
    print ('Failed to create socket. Error code' )
    sys.exit()

print ('Socket Created')
host = '服务器绑定域名或者服务器公网ip'
# host = 'localhost'

port = 8888 #和服务器端打开端口必须一致
try:
    remote_ip = socket.gethostbyname(host)

except socket.gaierror:
    #could not resolve
    print ('Hostname could not be resolved. Exiting')
    sys.exit()

print ('Ip address of ' + host + ' is ' + remote_ip)

#Connect to remote server
s.connect((remote_ip , port))

print ('Socket Connected to ' + host + ' on ip ' + remote_ip)
#Send some data to remote server
print('[%s]' % ctime())
reply = s.recv(4096)
print (reply)

def rec(receiver):
    while 1:
        try:
            reply=receiver.recv(1024)
        except OSError:
            print("Conversation ended,bye")
            return
        if not (reply.decode()):
            print("Conversation ended,bye")
            return
        else:
            print("Ta said: "+reply.decode())

threading._start_new_thread(rec,(s,))
message=input()
while message:
    try :
        #Set the whole string
        s.sendall(message.encode())
    except OSError:
        #Send failed
        print ('Sending failed')
        sys.exit()

    print ('Message send successfully')
    message=input()
print("按任意键退出")
exi=input()
sys.exit()
s.close()

Pyinstaller

可将客户端打包成一个exe执行文件。
(mac无法运行生成的exe)
pyinstaller打包

注意的坑

  1. #coding:utf-8必须写第一行。
  2. 主线程结束,其他线程也一起跟着结束
  3. 云服务器的端口开放问题,先在安全组添加的时候,第一个空要填0.0.0.0/0,这样才是所有用户都能访问,然后一定要看一下云服务器的防火墙开没开这个端口。centos防火墙开启端口
声明:本文内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎进行举报,并提供相关证据,工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。