2013-09-05 163 views
2

我得面對以下問題。也許有人可以幫助我。恢復快照後恢復套接字

我想要實現的是虛擬機內的服務(使用虛擬機/ WinXP的 )應通過套接字(客戶端)(1)將數據發送到主機。然後,主機 (套接字服務器)拍攝當前系統(2)的快照,向虛擬機(再次通過套接字)發送確認(3)到 ,確定每個動作都已完成並且服務 可以繼續(4)。

Service            Host 
=========            ======= 

Service sends specific data (1) 

     ---------------------------------------->  
                 Invoke Snapshot (2) 
| On restore socket gets destroyed (X) | 
| No ACK can be accepted -- Endless Loop|    Send ACK (3) 

     <---------------------------------------- 

Accept ACK and continue (4) 

當我將vm恢復到先前採用的狀態時,會出現問題。 軟件等待確認繼續。該虛擬機需要一些時間來恢復其網絡(3-5秒,直到「您的網絡電纜現在插入...」在 托盤中),並且這使插槽(X)崩潰了 。

我對此沒有解決方法。該服務是用C語言編寫的。主機是一個 python腳本。在我看來,睡眠是最糟糕的解決方案。由於高負荷,直到發生事情的時間是不可預測的。

我不能想出如何解決這個問題的好主意。如果你能幫助我,那將是 。

在此先感謝!

編輯:

@alk:我的假設,因爲客戶端未連接到服務器了(不同的狀態,由於恢復,並失去了一會兒我猜連接)

這裏來自服務的C代碼。我迷上某些系統調用,當一個系統調用被稱爲

#include <stdio.h> 
#include <winsock2.h> 
#include <stdarg.h> 

#pragma comment(lib,"ws2_32.lib") //Winsock Library 

WSADATA wsa; 
SOCKET s; 
struct sockaddr_in server; 
char buffer[1024]; 
char ack[1024]; 
int recv_size; 

int mpex_send(const char *str, ...) 
{ 
    // Build String 
    va_list va; 
    va_start(va, str); 
    vsnprintf(buffer, sizeof(buffer), str, va); 
    va_end(va); 

    // Init 
    printf("\nInitialising Winsock..."); 
    if (WSAStartup(MAKEWORD(2,2),&wsa) != 0) 
    { 
     printf("Failed. Error Code : %d",WSAGetLastError()); 
     return 1; 
    } 

    printf("Initialised.\n"); 

    //Create a socket 
    if((s = socket(AF_INET , SOCK_STREAM , 0)) == INVALID_SOCKET) 
    { 
     printf("Could not create socket : %d" , WSAGetLastError()); 
    } 

    printf("Socket created.\n"); 


    server.sin_addr.s_addr = inet_addr("192.168.56.1"); 
    server.sin_family = AF_INET; 
    server.sin_port = htons(42000); 

    //Connect to remote server 
    if (connect(s , (struct sockaddr *)&server , sizeof(server)) < 0) 
    { 
     puts("connect error"); 
     return 1; 
    } 

    puts("Connected"); 
    //Send some data 
    if(send(s , buffer , strlen(buffer) , 0) < 0) 
    { 
     puts("Send failed"); 
     return 1; 
    } 
    puts("Data Send\n"); 

    //Receive a reply from the server 
    while(1) 
    { 
     if((recv_size = recv(s , ack , 2000 , 0)) == SOCKET_ERROR) 
     { 
      puts("recv failed"); 
     } 

     puts("Reply received\n"); 
     ack[recv_size] = '\0'; 
     puts(ack); 
     // Important, put \n after ack 
     if (strcmp("ack\n", ack) == 0) 
     { 
      puts("Got it"); 
      break; 
     } 
    } 
    closesocket(s); 
    WSACleanup(); 
    return 0; 
} 
+1

是否服務問題阻塞'recv'這將導致它等待來自主機的ACK? – JackCColeman

+0

你怎麼確切地來到這個假設「* ...並且這會使套接字(X)崩潰*」並且你確切地要螞蟻來表達? – alk

+0

但是,如果您可以提供描述掛起過程的部分的源代碼,我們可以提供更多的野生猜測,但(希望)會提供答案。 – alk

回答

2

我設法解決我的問題的代碼被執行。也許有一天會遇到相同的,所以希望這有助於。

在發送來自C代碼的第一條消息後,它將進入循環狀態,嘗試創建並打開一個套接字(請參見上面的源代碼)。如果他們成功,他們就會破裂循環。之後,我循環一個socket.recv以獲取主機的確認。

在這種狀態下,主機收到消息並進入ack flooding狀態,並向所有連接的客戶機發送ack消息。所以這條消息被髮送到新的連接以及破壞的連接。

C代碼接收到ack後,會向主機發送ack_ack以停止泛洪。

此頁面對python服務器部分非常有用。 http://www.binarytides.com/code-chat-application-server-client-sockets-python/

希望這有助於