[英]Python SSL Socket: receiving and sending from both server and client
好的,所以我試圖通過SSL套接字連接在服務器和客戶端之間來回通信。 我認為最好的方法就是在每個中實現2個線程,每個線程分別充當服務器和客戶端。但是當我實現這個代碼時(顯然在其他服務器/客戶端使用相對的相應端口) :
#secserv.py
import socket
from OpenSSL import SSL
import threading
import time
class SecureIn(threading.Thread):
context = SSL.Context(SSL.SSLv23_METHOD)
context.use_privatekey_file('key')
context.use_certificate_file('cert')
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s = SSL.Connection(context, s)
s.bind(('', 5570))
def run(self):
while True:
self.s.listen(5)
(connection, address) = self.s.accept()
print repr(connection.recv(5570))
class SecureOut(threading.Thread):
time.sleep(6)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('localhost', 12345))
sslSocket = socket.ssl(s)
print repr(sslSocket.server())
print repr(sslSocket.issuer())
def run(self):
sslSocket.write('Hello secure socket\n')
s.close()
si = SecureIn()
si.start()
time.sleep(6)
so = SecureOut()
so.start()
我收到此錯誤:
Traceback (most recent call last):
File "secserv.py", line 25, in <module>
class SecureOut(threading.Thread):
File "secserv.py", line 28, in SecureOut
s.connect(('localhost', 12345))
File "/usr/lib/python2.7/socket.py", line 224, in meth
return getattr(self._sock,name)(*args)
socket.error: [Errno 111] Connection refused
或者,我嘗試使用獨立服務器向所有客戶端發送廣播消息。 我已經搜索了高低,但我似乎無法找到一種工作方式來使用SSL套接字,只有常規套接字。 當我嘗試s.write()
或s.sendall()
我收到此錯誤:
Traceback (most recent call last):
File "secserv.py", line 19, in <module>
s.write('hello client\n')
OpenSSL.SSL.Error: [('SSL routines', 'SSL_write', 'uninitialized')]
從這段代碼:
import socket
from OpenSSL import SSL
context = SSL.Context(SSL.SSLv23_METHOD)
context.use_privatekey_file('key')
context.use_certificate_file('cert')
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s = SSL.Connection(context, s)
s.bind(('', 12345))
while True:
s.listen(5)
(connection, address) = s.accept()
print repr(connection.recv(12345))
#This could also be s.sendall()
s.write('hello client\n')
請幫我StackOverFlow,你是我唯一的希望。 我知道這應該很容易,但是我的大腦在這一點上非常緊張,我再也想不到了。
另外,我對python很新,所以很有可能它的操作方式/加載類/等等,我只是沒有得到。
編輯:好的,我知道這段代碼很糟糕。 它不是一個推向市場的產品,它永遠不會在現場運行,這只是我試圖讓一個概念起作用,而這個概念是:讓服務器和客戶端通過python ssl連接向對方發送消息。
我知道這是可怕的代碼,但我只需要知道如何讓服務器發回消息,因為無論何時我嘗試它都會在最后得到錯誤。
您的設計似乎在許多層面上都是錯誤的。
首先,您不需要兩個插槽來向兩個方向發送數據; 套接字是雙向的。
並且您可能不希望從服務器返回到客戶端 - 這可能在localhost測試中起作用,但是一旦部署到Internet,大多數客戶端將位於NAT路由器后面,並且不會有公共地址你可以連接到。
同時,你的邏輯很奇怪。 您在一個方向上開始連接,然后睡6秒,然后在另一個方向上開始連接。 你為什么想這么做?
如果服務器調用其SecureOut
之前,甚至在同一時間,作為客戶端調用其SecureIn
,它會嘗試連接有任何人聽,這將讓正是你所看到的錯誤了。
此外,每個線程都有一個非常奇怪的運行循環:
def run(self):
while True:
self.s.listen(5)
(connection, address) = self.s.accept()
print repr(connection.recv(5570))
這一次只接受一個連接,從中讀取一次,然后泄漏連接,再也不與它通話,然后去獲取下一個客戶端。 (我也不確定在已經正在收聽的套接字上再次調用listen(5)
是否真的有效。或者它的功能。當然,它無法完成。 (這不是真的 - 例如,如果一個客戶端連接然后在你調用recv
之前消失,你可能會得到一個例外,你沒有抓到,所以你的程序將退出...)這就是你想要的?
另外,為什么recv(5570)
? 該數字是要讀取的最大字節數,而不是端口號。
為什么打印字符串的repr
?
同時,你是否意識到recv
,無論你為緩沖區長度傳遞什么,都不能保證獲得整個消息(或者只獲得一條消息而不是兩條消息,如果你有一個客戶端發送了多個消息)? 它幾乎可以肯定地在localhost上工作,並且通過這么小的消息它可能在互聯網上大部分時間都可以工作,但不是所有的時間。
您似乎也對類變量和實例變量之間的區別感到困惑,因為您在SecureIn
和SecureOut
設置了一堆類變量。 這意味着如果你有兩個類的實例,它們會共享相同的SSL.Context
等。即使你不需要在現實生活中同時擁有兩個實例,為了測試你幾乎肯定會想要創建一個新實例,你會想要創建一個新的套接字等,而不是繼續使用舊的。 所以不是這樣的:
class SecureIn(threading.Thread):
context = SSL.Context(SSL.SSLv23_METHOD)
context.use_privatekey_file('key')
context.use_certificate_file('cert')
…
做這個:
class SecureIn(threading.Thread):
def __init__(self):
self.context = SSL.Context(SSL.SSLv23_METHOD)
self.context.use_privatekey_file('key')
self.context.use_certificate_file('cert')
…
(或者你可以把它放在run方法中,當然。)
基本上,無論是否使用SSL,這都不太可能有用。 我建議你退后一步,閱讀一些教程,並編寫適用於普通TCP套接字的東西,然后擔心如何對其進行SSL-ize。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.