2014-12-08 45 views
0

我想創建一個應用程序,將數據從C++中的程序發送到Matlab中的另一個程序。 數據的大小爲〜100 double @ 1000Hz,我在達到該頻率時(即使在本地主機上)也遇到了問題。性能Windows Socket在C++與Matlab

使用套接字的默認參數我得到〜100Hz。另外我嘗試使用值TCP_NODELAY爲false,但這使情況變得更糟。處理器是i7-2600 @ 3.4赫茲,所以肯定不是問題。此外,目前我對數據進行的唯一處理是保存它,因此也存在耗時的過程。

另外我相信我可以達到1000赫茲,因爲如果我刪除發送命令,輸出文件具有> 1000赫茲。

的初始化代碼:

ConnectSocket = INVALID_SOCKET; 
// Initialize Winsock 
WSADATA wsaData; 
struct addrinfo *result = NULL, 
      *ptr = NULL, 
      hints; 
int iResult; 
iResult = WSAStartup(MAKEWORD(2,2), &wsaData); 
if (iResult != 0) { 
    printf("WSAStartup failed with error: %d\n", iResult); 
} 

ZeroMemory(&hints, sizeof(hints)); 
hints.ai_family = AF_UNSPEC; 
hints.ai_socktype = SOCK_STREAM; 
hints.ai_protocol = IPPROTO_TCP; 

// Resolve the server address and port 
iResult = getaddrinfo("localhost", DEFAULT_PORT, &hints, &result); 
if (iResult != 0) { 
    printf("getaddrinfo failed with error: %d\n", iResult); 
    WSACleanup(); 
} 
// Attempt to connect to an address until one succeeds 
for(ptr=result; ptr != NULL ;ptr=ptr->ai_next) { 

    // Create a SOCKET for connecting to server 
    ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol); 
    if (ConnectSocket == INVALID_SOCKET) { 
     printf("socket failed with error: %ld\n", WSAGetLastError()); 
     WSACleanup(); 
    } 

    // Connect to server. 
    iResult = connect(ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen); 
    if (iResult == SOCKET_ERROR) { 
     closesocket(ConnectSocket); 
     ConnectSocket = INVALID_SOCKET; 
     continue; 
    } 
    break; 
} 

freeaddrinfo(result); 

if (ConnectSocket == INVALID_SOCKET) { 
    printf("Unable to connect to server!\n"); 
    WSACleanup(); 
} 

其中主要(或完全地)是從微軟的網頁複製。 對於發送功能,我們有:

if (RecordingFlag){ 
      packet[51]=values[35]; 
      packet[52]=numchDAQ; 
      for (i=0;i<values[35];i++){ 
       fprintf(file,"%.3lf,",values[i]); 
       packet[i] =(double)values[i]; 
      } 
      //DAQ 
      if (numchDAQ >0){ 
       DAQmxReadAnalogF64(taskHandle,1,10.0,DAQmx_Val_GroupByChannel,data,16,&read,NULL); 
       for(i=0;i<numchDAQ;i++){ 
        fprintf(file,"%.3lf,",data[i]); 
        packet[(int)packet[51]+i]=(double)data[i]; 
       } 
      } 
      //Timestamp 
      GetSystemTime(&st); 
      SystemTimeToFileTime(&st,&ft); 
      diftime= ((((ULONGLONG) ft.dwHighDateTime) << 32) + ft.dwLowDateTime)/10000 - MSEC_TO_UNIX_EPOCH; 
      fprintf(file,"%llu",diftime); 
packet[0]=prueba; 
prueba++; 
      send(ConnectSocket, (const char*)packet, sizeof(double)*53, 0); 
      fprintf(file,"\n"); 
     } 

調用該函數每秒1000次。 我想問題是Windows不會快速創建套接字,因爲它正在等待來自服務器的ACK。但是,Matlab中的服務器也很簡單:

import java.net.ServerSocket 
    import java.io.* 
    j=1; 
    i=0; 
    server_socket = []; 
    input_socket = []; 
    dataByte = int8(zeros (1,424)); 
    dataDouble = zeros(10000,53); 
    while (1) 
     try 
      i= i+1; 
      fprintf(1, 'Trying to connect %d\n',i); 
      server_socket = ServerSocket(31415); 
      server_socket.setSoTimeout(5000); 
      input_socket = server_socket.accept; 
      fprintf(1, 'Client connected\n'); 
      while (1) 
       input_stream = input_socket.getInputStream; 
       d_input_stream = DataInputStream(input_stream); 
       bytes_available = input_stream.available; 
       while(bytes_available>0 && j<10000) 
        %fprintf(1, 'Reading %d bytes\n', bytes_available); 
        for i =1:424 
         dataByte(i)= d_input_stream.readByte; 
         bytes_available = bytes_available-1; 
        end 
        dataDouble(j,:) = typecast(dataByte,'double'); 
        j=j+1; 
       end 
      end 

      % cleanup 
      input_socket.close; 
     catch 
      if ~isempty(server_socket) 
       server_socket.close; 
      end 

      if ~isempty(input_socket) 
       input_socket.close 
      end 

      % pause before retrying 
      %pause(1); 
     end 
    end 

即使沒有進行類型轉換,我也會得到相同的結果。

有關如何解決此問題的任何想法?

編輯:問題是在Matlab中,它讀取的信息太慢。我改變了代碼,現在完美工作 while(bytes_available> 0 & & j < 1000) d_input_stream.read(dataByte,0,424); bytes_available = bytes_available-424; dataDouble(j,:) = typecast(dataByte,'double'); j = j + 1; end

+2

你不想成爲試圖建立1000插孔的第二。只需創建一個套接字,並在數據通過它傳輸時保持打開狀態。 – sjdowling 2014-12-08 09:35:58

+1

我不正確地表達我的自我。我沒有創建1000個套接字。我創建一個並嘗試每秒發送1000個數據包。 – Priack 2014-12-10 02:47:43

回答

0

問題出在Matlab上,它讀取的信息太慢了。我改變了代碼和現在的作品完美

while(bytes_available>0 && j<1000) 
    d_input_stream.read(dataByte,0,424); 
    bytes_available = bytes_available-424; 
    dataDouble(j,:) = typecast(dataByte,'double'); 
    j=j+1; 
end 

- Priack