最近,我设法在我的PC和Raspberry Pi上创建套接字,以实现两个设备之间的通信。目前,客户端能够自动向服务器发送消息。我想知道,如果有可能修改脚本来发送tcp数据包而不是纯文本消息,因为我非常希望将来使用我的PC来控制覆盆子pi,而不需要ssh / etc。
我看过一些例子,但由于我在编写自己的脚本/代码方面没有太多经验,所以我不太清楚如何去做。如果有人能够通过解释和一些例子向我指导正确的方向,我将不胜感激。
无论如何这里是我正在运行的服务器/客户端脚本:
客户端:
import socket
import sys
import struct
import time
#main function
if __name__ == "__main__":
if(len(sys.argv) < 2) :
print 'Usage : python client.py hostname'
sys.exit()
host = sys.argv[1]
port = 8888
#create an INET, STREAMing socket
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except socket.error:
print 'Failed to create socket'
sys.exit()
print 'Socket Created'
try:
remote_ip = socket.gethostbyname( host )
s.connect((host, port))
except socket.gaierror:
print 'Hostname could not be resolved. Exiting'
sys.exit()
print 'Socket Connected to ' + host + ' on ip ' + remote_ip
#Send some data to remote server
message = "Test"
try :
#Set the whole string
while True:
s.send(message)
print 'Message sent successfully'
time.sleep(1)
print 'Sending...'
except socket.error:
#Send failed
print 'Send failed'
sys.exit()
def recv_timeout(the_socket,timeout=2):
#make socket non blocking
the_socket.setblocking(0)
#total data partwise in an array
total_data=[];
data='';
#beginning time
begin=time.time()
while 1:
#if you got some data, then break after timeout
if total_data and time.time()-begin > timeout:
break
#if you got no data at all, wait a little longer, twice the timeout
elif time.time()-begin > timeout*2:
break
#recv something
try:
data = the_socket.recv(8192)
if data:
total_data.append(data)
#change the beginning time for measurement
begin=time.time()
else:
#sleep for sometime to indicate a gap
time.sleep(0.1)
except:
pass
#join all parts to make final string
return ''.join(total_data)
#get reply and print
print recv_timeout(s)
s.close()
服务器:
import socket
import sys
from thread import *
HOST = '' # Symbolic name meaning all available interfaces
PORT = 8888
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print 'Socket created'
try:
s.bind((HOST, PORT))
except socket.error , msg:
print 'Bind failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1]
sys.exit()
print 'Socket bind complete'
s.listen(10)
print 'Socket now listening'
#Function for handling connections
def clientthread(conn):
#Sending message to connected client
conn.send('Welcome to the server. Receving Data...\n') #send only takes string
#infinite loop so that function do not terminate and thread do not end.
while True:
#Receiving from client
data = conn.recv(1024)
reply = 'Message Received at the server!\n'
print data
if not data:
break
conn.sendall(reply)
conn.close()
#now keep talking with the client
while 1:
#wait to accept a connection
conn, addr = s.accept()
print 'Connected with ' + addr[0] + ':' + str(addr[1])
#start new thread
start_new_thread(clientthread ,(conn,))
s.close()
答案 0 :(得分:4)
socket.socket(socket.AF_INET, socket.SOCK_STREAM)
已经创建了一个连接,可以在两台机器之间提供可靠的字节流。这使用TCP,它位于IP和以太网之上。后两者是基于包的,而TCP在其上创建连续字节流。它还增加了一些错误检查和纠错功能,因此非常可靠。
老实说,我不明白你想要通过什么来实现你想要达到的目标&#34;发送数据包&#34;。你不想做的是自己创建一个TCP的实现,因为这是一个非常重要的任务,所以发送RAW数据包就不行了。一般来说,即使使用TCP也已经相对较低,除非确实有必要,否则应该避免使用。
使用例如ZeroMQ你得到一个基于消息的界面,为你做所有的传输。它在TCP(或其他传输)之上这样做,并为例如增加了更多的纠错。断开。在那里,你还有类似&#34;数据包&#34;之类的内容,但这些内容与在下面发送它需要多少TCP或IP数据包无关。如果您不想实现特定协议,我建议您使用此框架而不是低级TCP套接字。
另一个简单的替代方法是使用HTTP,Python中也存在现有代码。缺点是它始终是一方启动一些沟通而另一方只回复。如果您想要某种有效的通知,您必须轮询或使用诸如延迟答案之类的黑客。
答案 1 :(得分:1)
您已经在发送数据包 - 这些数据包突然发生在当前包含文本数据。尝试在标准库中查看pickle并进入pyro。