2013-07-06 244 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現有的代碼。缺點是始終只有一方發起某種溝通,而另一方只能回覆。如果你想要某種活動的通知,你必須輪詢或使用黑客,如延遲答案。

相關問題