2 Stimmen

Erstellung des Websockets mit dem C++-Server

Ich habe den Server in C++ erstellt, um eine Verbindung zu WebSocket herzustellen, aber irgendwie wurde keine Verbindung mit dem Websocket hergestellt. Der WebSocket zeigt an, dass die Verbindung geschlossen ist, und es gibt auch ein Problem im C++-Server, da beim zweiten Aufruf des Servers vom WebSocket aus folgender Fehler angezeigt wird: double free or corruption (out). Ich habe sehr viel Zeit damit verbracht. Hier ist der Code: c++

#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 C++ und was ist die Antwort, die an das WebScoket gesendet wird.

1voto

hmjd Punkte 118293

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

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 könnten einfach die cmd.c_str() direkt an popen() statt der Zuweisung und Auffüllung der command Puffer für diesen Zweck:

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

Ich würde empfehlen, Folgendes zu ersetzen char* con std::string wo es möglich ist, und erlauben Sie ihm, den Speicher für Sie zu verwalten und vom Stapel zugewiesene Puffer zu verwenden, anstatt dynamisch Puffer zuzuweisen, wenn ein std::string ist nicht angemessen. 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;
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X