簡體   English   中英

使用C ++服務器制作Websocket

[英]making the Websocket using the c++ server

我在用c ++制作服務器以連接到WebSocket,但是不知何故,它沒有與websocket連接。 WebSocket顯示連接已關閉,並且在c ++服務器中也存在一些問題,因為從WebSocket第二次調用服務器時,它顯示以下錯誤-兩次釋放或損壞(輸出)。 我花了很多時間。 這是代碼: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);
}

這是Websocket代碼:

<!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>

請幫幫我,C ++中的問題是什么以及要發送到WebScoket的響應是什么。

這是一個問題(在executeShellCommand()函數中):

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

您可以直接將cmd.c_str()傳遞給popen()而不是為此目的分配和填充command緩沖區:

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

我建議在可能的情況下用std::string替換char* ,並允許它為您管理內存,並在不適合使用std::string情況下使用堆棧分配的緩沖區而不是動態分配緩沖區。 例如:

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;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM