2013-07-06 192 views
5

近日,笔者设法创造我的电脑和我的树莓派的插座,以使两个设备之间的通信。目前,客户端能够自动发送消息到服务器。我想知道,是否可以修改脚本来发送tcp数据包而不是纯文本消息,因为我非常想在将来使用我的PC控制覆盆子pi,而不需要ssh/etc。发送/接收数据包与TCP套接字

我看了一些例子,但我没有在写我自己的脚本/代码太多的经验,我不是很清楚如何去这样做。如果有人能够在正确的方向引导我解释并尽可能举例,我将不胜感激。

反正这里是我目前运行的服务器/客户端脚本:

客户:

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

您已经发送的数据包 - 那些数据包突然包含此刻的文本数据。尝试在标准库中查找腌菜,并尝试pyro

+0

我读了RAW插槽,以及它们如何发送/接收TCP/IP原始数据包,并需要在脚本中手动指定的TCP和IP报头。将数据包发送到树莓派来控制它的一些功能会更好吗? 对不起,如上所述,我没有太多的套接字和数据包的经验。我正在运行的脚本是标准套接字,并且“消息”有效载荷通过TCP传输,是否可以修改脚本部分以发送数据包(而不是文本数据)来完成这项工作? – intensified

+0

此外,socket.error处理是检查发送数据中的错误的唯一方法吗?或者有其他方法可以进行错误检查,例如,当服务器收到数据时,它会执行冗余检查以确保在传输过程中没有数据丢失? – intensified

3

socket.socket(socket.AF_INET, socket.SOCK_STREAM)已经创建了提供两个机器之间的字节的可靠流的连接。这使用TCP,它位于IP和以太网之上。后两者是基于软件包的,而TCP则在其上创建一个连续字节流。它还增加了一些错误检查和纠错,所以它非常可靠。

老实说,我不明白你要实现你所说的“发送数据包”是什么。你不想做的是自己创建一个TCP的实现,因为这是一个不重要的任务,所以发送RAW数据包就没有了。一般来说,即使使用TCP也是相对较低的水平,除非确实需要,否则应该避免。

使用例如ZeroMQ你会得到一个基于消息的界面,为你做所有的传输。它是在TCP(或其他传输)的基础上进行的,并增加了更多的纠错。断开。在那里,你也有类似“数据包”的东西,但这些数据独立于下面发送它所需的TCP或IP数据包的数量。如果你不想实现一个特定的协议,我建议你使用这个框架,而不是低级TCP套接字。

另一种简单的替代方法是使用HTTP,对此也有在Python现有的代码。缺点是始终只有一方发起某种沟通,而另一方只能回复。如果你想要某种活动的通知,你必须轮询或使用黑客,如延迟答案。

相关问题