2012-03-25 11 views
2

Ich machte den Server in C++, um eine Verbindung zu WebSocket aber irgendwie, es war keine Verbindung mit dem Websocket. Der WebSocket zeigt an, dass die Verbindung geschlossen ist, und es gibt auch ein Problem im C++ - Server, da beim zweiten Aufruf von WebSocket an den Server der folgende Fehler angezeigt wird: doppelt frei oder beschädigt (out). Ich habe viel Zeit damit verbracht. Hier ist der Code: C++macht den Websocket mit dem C++ Server

#include<iostream> 
#include <string> 
#include <stdio.h> 
#include <unistd.h> 
#include <stdlib.h> 
#include <errno.h> 
#include <string.h> 
#include <time.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <arpa/inet.h> 
#include <netdb.h> 


using namespace std; 

string getConnectionKey(char*); 
void acceptConnection(int, const char*); 
void readConnection(int); 
void bail(char*); 
string executeShellCommand(const string&); 
string getBase64Encoded(string); 
char *getClientKey(char*); 
string getSHA1Hash(string); 

int main() 
{ 
    char srvr_adr[] = "127.0.0.1"; 
    char srvr_port[] = "9099"; 

    struct sockaddr_in adr_srvr; 
    struct sockaddr_in adr_clnt; 

    socklen_t len_inet; 
    int s;  // Server Socket 
    int c;  // Client Socket 
    int z; 
    char *data; 
    char readdata[256]; 

    int count = 2; 

    data = (char*)malloc(sizeof(char)*128); 

    s = socket(PF_INET, SOCK_STREAM, 0); 

    if(s == -1) 
    bail("socket()"); 

    memset(&adr_srvr,0,sizeof(adr_srvr)); 
    adr_srvr.sin_family = AF_INET; 
    adr_srvr.sin_port = htons(atoi(srvr_port)); 

    if(strcmp(srvr_adr,"*")!=0) 
    { 
    adr_srvr.sin_addr.s_addr = inet_addr(srvr_adr); 
    if(adr_srvr.sin_addr.s_addr == INADDR_NONE) 
     bail(" INVALID ADRESS \n"); 
    } 
    else /* WILD ADDRESS*/ 
    adr_srvr.sin_addr.s_addr = INADDR_ANY; 

    len_inet = sizeof adr_srvr; 
    z = bind(s,(struct sockaddr*)&adr_srvr, len_inet); 

    if(z==-1) 
    bail("bind(2)"); 

    z = listen(s,10); 

    if(z==-1) 
    bail("listen(2)"); 

    for(;;) 
    { 
    len_inet = sizeof(adr_clnt); 
    c = accept(s, (struct sockaddr*)&adr_clnt,&len_inet); 

    if(c==-1) 
     bail("accept(2)"); 

    readConnection(c); 

    close(c); 
    } 
    return 0; 
} 

void readConnection(int c) 
{ 
    int z; 
    char readdata[256]; 

    // READING 
    z = read(c,readdata, sizeof(readdata)-1); 
    if(z==-1) 
     bail("read(2)"); 
    else if(strlen(readdata)>0) 
     printf(" READ \n%s\n", readdata); 

    string key = getConnectionKey(readdata); 
    cout<<" KEY "<<key<<endl; 
    acceptConnection(c, key.c_str()); 
} 

void acceptConnection(int c, const char *key) 
{ 
    int z;  
    char response[] = "HTTP/1.1 101 Switching Protocols\nUpgrade: websocket\nConnection: Upgrade\nSec-WebSocket-Accept: "; 
    char *output; 
    output = (char*)malloc(sizeof(char) * (strlen(key) + strlen(response) + 1)); 
    strcat(output, response); 
    strcat(output, key); 

    cout<<" output "<<output<<endl; 
    // WRITING 
    z = write(c, output, strlen(output)); 
    if(z == -1) 
     bail("write(2)"); 

    printf(" Connection Done \n"); 
} 

string getConnectionKey(char *str) 
{ 
    char *start,*end,*key; 
    int len; 
    string s("258EAFA5-E914-47DA-95CA-C5AB0DC85B11"); 

    // GET CLIENT KEY 
    key = getClientKey(str); 

    // Appending the key 
    s = key + s; 

    // SHA1 HASH 
    string out = getSHA1Hash(s); 
    //hashwrapper *h = new sha1wrapper(); 
    //string out = h->getHashFromString(s); 

    // BASE 64 ENCODING 
    string encoded = getBase64Encoded(out); 
    //encoded = (char*)malloc(sizeof(char)*256); 
    //strcpy(encoded, getBase64Encoded(out)); 

    free(key); 
    //delete h; 
    return encoded; 
} 
char *getClientKey(char *str) 
{ 
    int len; 
    char *start,*end,*key; 

    start = strstr(str, "Sec-WebSocket-Key:"); 
    if(start == NULL) 
    return false; 
    start += 17; 

    end = strstr(start, "=="); 
    if(end == NULL) 
    return false; 

    end++; 

    while(!(*start>=65 && *start<=90 || *start >= 97 && *start<=122 || *start>=48 && *start<=57 || *start == '+' || *start=='/')) 
    start++; 
    len = end - start + 1; 
    key = (char*) malloc(sizeof(char) * (len+1)); 
    strncpy(key,start,len); 

    return key; 
} 

string getBase64Encoded(string s) 
{ 
    int len; 
    string str=""; 
    len = s.length(); 
    char *command; 

    for(int i=len-1 ; i>=1; i=i-2) 
    { 
    str = s.substr(i-1,2) + str; 
    str = "\\x" + str; 
    } 
    if(len%2==1) 
    { 
    str = s[0] + str; 
    str = "\\x" + str; 
    } 
    // making the command to be send to shell 
    str = "printf \"" + str ; 
    str = str + "\" | base64"; 

    cout<<endl<<" STRING "<<str<<endl; 
    return executeShellCommand(str); 
} 
string getSHA1Hash(string str) 
{ 
    int len ; 
    string output; 
    str = "printf \""+str; 
    str = str +"\" | sha1sum"; 
    cout<<str<<endl; 
    output = executeShellCommand(str); 

    return output.substr(0,output.length()-4);; 
} 
string executeShellCommand(const string& cmd) 
{ 
    FILE *fpipe; 

    if (!(fpipe = (FILE*)popen(cmd.c_str(),"r"))) 
    { // If fpipe is NULL 
    perror("Problems with pipe"); 
    exit(1); 
    } 

    char buf[256] = ""; 
    string line=""; 
    while (fgets(buf, sizeof buf, fpipe) ) 
    { 
    if(strlen(buf)>0) 
     line.append(buf); 
    memset(buf, 0, sizeof(buf)); 

    } 
    // CLOSE THE PIPE 
    pclose(fpipe); 

    return line; 
} 
void bail(char *on_what) 
{ 
    if(errno!=0) 
    { 
    fputs(strerror(errno), stderr); 
    fputs(":", stderr); 
    } 
    fputs(on_what, stderr); 
    fputs("\n",stderr); 
} 

Hier ist der Websocket Code:

<!doctype html> 
<html> 
<head> 
<meta charset="UTF-8"> 
<title>WebSocket Chat</title> 
</head> 
<body> 
<h1>WebSocket Chat</h1> 
<section id="content"></section> 
<input id="message" type="text" tabindex="1"/> 
<textarea id="show"> 
</textarea> 
<script src="http://www.google.com/jsapi"></script> 
<script>google.load("jquery", "1.3")</script> 
<script src="http://jquery-json.googlecode.com/files/jquery.json-2.2.min.js"></script> 
<!--script src="http://jquery-websocket.googlecode.com/files/jquery.websocket-0.0.1.js"></script--> 
<script src="/js/jquery.websocket-0.0.1.js"></script> 
<script type="text/javascript"> 

/*var ws = $.websocket("ws://127.0.0.1:9099/", 
      { 
      events: { 
          message: function(e) 
          { 
           alert("e.data"); 
           $('#content').append(e.data + '<br>') 
          } 
        } 
      });*/ 
var websocketConnection = new WebSocket("ws://127.0.0.1:9099/"); 
websocketConnection.onopen = function(ev) 
{ 
     showmsg('Connected to the echo service'); 
}; 
websocketConnection.onerror = function(ev) 
{ 
    showmsg(" ERROR : ".ev.data); 
} 
websocketConnection.onclose = function(ev) 
{ 
    showmsg(" Connection Closed"); 
}; 
websocketConnection.onmessage = function(event) 
{ 
     showmsg(event.data); 
     $('#content').append(event.data+"<br>"); 
}; 
showmsg(" CURRENT STATE "+websocketConnection.readyState); 
if(!websocketConnection) 
    showmsg(" object null "); 
websocketConnection.send("Hello Echo Server"); 

$('#message').change(function(){ 
     flag = ws.send('message', this.value); 
     if(!flag) 
     alert("not send"); 

     this.value = ''; 
     }); 
function showmsg(content) 
{ 
    $('#show').val(content+"<br>"); 
} 
</script> 
</body> 
</html> 

Bitte Helfen Sie mir, was ist das Problem in der C++ und was ist die Antwort auf die WebScoket gesendet werden .

Antwort

1

Dies ist ein Problem (in executeShellCommand()-Funktion):

if (!(fpipe = (FILE*)popen(cmd.c_str(),"r"))) 

I:

command = (char*) malloc(sizeof(char) * cmd.length() ); 
line = (char*)malloc(sizeof(char)*256); 
line[0] = '\0'; 
//cout<<" COMMAND "<<cmd<<endl; 
strcpy(command, cmd.c_str()); // Writes one beyond the end of the 
           // 'command' buffer as no space allocated 
           // for null terminator 

Sie einfach die cmd.c_str() direkt an popen() statt Aufteilung und bevölkern die command Puffer für diesen Zweck passieren könnte würde empfehlen, char* mit std::string zu ersetzen, wo es möglich ist, und es erlauben, Speicher für Sie zu verwalten und Stapel zugewiesene Puffer anstelle von zu verwenden Puffer dynamisch zuweisen, wenn std::string nicht geeignet ist. Zum Beispiel:

std::string executeShellCommand(const std::string& cmd) 
{ 
    FILE *fpipe; 

    if (!(fpipe = (FILE*)popen(cmd.c_str(),"r"))) 
    { // If fpipe is NULL 
    perror("Problems with pipe"); 
    exit(1); 
    } 

    char buf[256] = ""; 
    std::string line; 
    while (fgets(buf, sizeof buf, fpipe) ) 
    { 
    line += buf; 
    memset(buf, 0, sizeof(buf)); 
    } 
    // CLOSE THE PIPE 
    pclose(fpipe); 

    return line; 
} 
+0

immer noch nicht funktioniert. An zweiter Stelle vom Web-Socket gibt es einen Speicherbeschädigungsfehler bei Zeile + = buf. Warum Websocket-Verbindung hergestellt wird, wenn der Schlüssel richtig gesendet wird. – cooldude

+0

Ich habe den Code geändert. Was ist das Problem? – cooldude