2014-09-02 128 views
0

我試圖從一個python客戶端向服務器發送和接收C結構數據,反之亦然。客戶端和服務器都可以在連接和交換數據方面順利進行。客戶端向服務器發送ctype結構,服務器再次發送它。問題是我不知道如何解釋客戶端收到的消息,並以結構格式提取數據。我最後的想法是讓一個python服務器和C客戶端相互交談並以預定義的結構交換數據。使用python和ctype通過套接字發送/接收數據結構

這裏是代碼我有一個客戶端和服務器在Python:

客戶端代碼

import socket 
import sys 
import time 

from ctypes import * 

class payload_t(Structure): 
    _fields_ = [("ms", c_ulong), 
       ("counter", c_ulong), 
       ("DHT_temperature", c_float), 
       ("DHT_humidity", c_float), 
       ("DS_temperature", c_float), 
       ("temperature_setpoint", c_float), 
       ("time_setpoint", c_float)] 

# Create a TCP/IP socket 
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 

# Connect the socket to the port where the server is listening 
server_address = ('localhost', 10000) 
print >>sys.stderr, 'connecting to %s port %s' % server_address 
sock.connect(server_address) 

try: 
    for i in range(0,10): 
     # Send data 
     payload=payload_t(i*1000,i+1,25.2,45.7,25.8,33.22,3600.0) 
     message = payload 
     # 'This is the message. It will be repeated.' 
     print 'length of message %d' % sizeof(message) 
     print 'sending "', message.ms, message.counter, message.DHT_temperature, message.DHT_humidity, message.DS_temperature, message.temperature_setpoint, message.time_setpoint, '"' 
     sock.sendall(message) 
     # time.sleep(0.1) 
     # Look for the response 
     amount_received = 0 
     amount_expected = sizeof(message) 

     while amount_received < amount_expected: 
      datap = sock.recv(sizeof(message)) 
      amount_received += len(datap) 
     print >>sys.stderr, 'received "%s"' % datap 
     print type(datap) 
     payload=payload_t() 
     datap.readinto(payload) 
     data=datap.readinto(payload_t) 
     data=struct.unpack(payload_t,datap) 
      print 'Received "', data.ms, data.counter, data.DHT_temperature, data.DHT_humidity, data.DS_temperature, data.temperature_setpoint, data.time_setpoint, '"' 

finally: 
    print >>sys.stderr, 'closing socket' 
    sock.close() 

服務器代碼

import socket 
import sys 
from ctypes import * 

class payload_t(Structure): 
    _fields_ = [("ms", c_ulong), 
       ("counter", c_ulong), 
       ("DHT_temperature", c_float), 
       ("DHT_humidity", c_float), 
       ("DS_temperature", c_float), 
       ("temperature_setpoint", c_float), 
       ("time_setpoint", c_float)] 

# Create a TCP/IP socket 
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 

# Bind the socket to the port 
server_address = ('localhost', 10000) 
print >>sys.stderr, 'starting up on %s port %s' % server_address 
sock.bind(server_address) 

# Listen for incoming connections 
sock.listen(1) 
payload=payload_t(0,0,0.0,0.0,0.0,0.0,0.0) 
while True: 
    # Wait for a connection 
    print >>sys.stderr, 'waiting for a connection' 
    connection, client_address = sock.accept() 

    try: 
     print >>sys.stderr, 'connection from', client_address 

     # Receive the data in small chunks and retransmit it 
     while True: 
      data = connection.recv(sizeof(payload)) 
      print >>sys.stderr, 'received "%s"' % data 
      if data: 
       print >>sys.stderr, 'sending data back to the client' 
       connection.sendall(data) 
      else: 
       print >>sys.stderr, 'no more data from', client_address 
       break 

    finally: 
     # Clean up the connection 
     connection.close() 

回答

0

首先,您目前傾倒收到的數據。您在每次循環迭代中重新分配變量'datap'。

做這樣的事情,而不是:

datap += sock.recv(sizeof(message) - amount_received) 

(當然,這還不是最高效的代碼,但你的想法。)

當你有你的結構在「從datap」變種組裝,使用'from_buffer'或'from_buffer_copy'方法將其加載到ctype類中。

payload = payload_t.from_buffer_copy(datap) 

後者在您的情況下更好,因爲當您重新綁定'datap'var時,緩衝區可能會消失。

+0

謝謝!它完美地工作。而且,顯然,我只需要每一步都初始化有效載荷。 – Betizad 2014-09-11 15:26:22

相關問題