2012-03-17 12 views
2

私はhtml5とそのwebsocketで新しいです!WebSocketをCコードでハンドシェイクする

今私はCで、私自身のWebSocketサーバーを作成しようとしてきたが、

それは私がちょうどたいCサーバからHTMLクライアントに「こんにちは、世界」を送信

私には難しいのですが、

私はハンドシェイクに困っています

onMessageとonOpenの両方がクライアント側で動作していません... !! WebSocketの\ rを\ nは

接続::アップグレード\ rを\ nは

私はちょうどサーバが

HTTP/1.1 101スイッチングプロトコル\ rを\ nは

アップグレードを送信する必要がある知っているから

秒-のWebSocket-受け入れ:私が受け取ったキー+ 258EAFA5-E914-47DA-95CA-C5AB0DC85B11

、それが行われなければなりません! //私が知っているところから... T_T

私はgoogleで走って少し作ったけど、今は動作しません!

あなたは私のミスが何であるか教えていただけますか?

===========要約================私が知りたい何

は、サーバがクライアントのHTMLにさえdoesntのを対応送信する方法でありますまだ接続している!私はUbuntuの中で働いている今、ソケットプログラミングのためのファイルポインタを使用するよう

は 今私のコードは、クライアントのソケット

write(clnt_sock, query, sizeof(query)); 

の記述子と書き込み()関数を使用して上記の対応が、それは正しいですかわからないイムまたは送信しますない

==================================

それは私のCサーバの

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <unistd.h> 
#include <arpa/inet.h> 
#include <sys/socket.h> 

void error_handling(char *message); 

int main(int argc, char *argv[]) 
{ 
    int serv_sock; 
    int clnt_sock; 
    int i=0; 
    char readHeader[500]={0}; 
    char* parsingHeader[10]; 
    char* saveOrigin; 
    char* saveKey; 
    char* magicKey="258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; 
    char query[105]="HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: "; 

    struct sockaddr_in serv_addr; 
    struct sockaddr_in clnt_addr; 
    socklen_t clnt_addr_size; 

    char message[]="Hello World!"; 

    if(argc!=2){ 
     printf("Usage : %s <port>\n", argv[0]); 
     exit(1); 
    } 

    serv_sock=socket(PF_INET, SOCK_STREAM, 0); 
    if(serv_sock == -1) 
     error_handling("socket() error"); 

    memset(&serv_addr, 0, sizeof(serv_addr)); 
    serv_addr.sin_family=AF_INET; 
    serv_addr.sin_addr.s_addr=htonl(INADDR_ANY); 
    serv_addr.sin_port=htons(atoi(argv[1])); 

    if(bind(serv_sock, (struct sockaddr*) &serv_addr, sizeof(serv_addr))==-1) 
     error_handling("bind() error"); 

    if(listen(serv_sock, 5)==-1) 
     error_handling("listen() error"); 

    clnt_addr_size=sizeof(clnt_addr); 
    clnt_sock=accept(serv_sock, (struct sockaddr*)&clnt_addr,&clnt_addr_size); 
    if(clnt_sock==-1) 
     error_handling("accept() error"); 
    read(clnt_sock,readHeader,355); 

     parsingHeader[0]=strtok(readHeader,"\r\n"); 

    for(i=1;i<6;i++) 
     parsingHeader[i]=strtok(NULL,"\r\n"); 

    saveOrigin=strtok(parsingHeader[4]," "); 
    saveOrigin=strtok(NULL," "); 
    saveKey=strtok(parsingHeader[5]," "); 
    saveKey=strtok(NULL," "); 

    strcat(saveKey,magicKey); 
    strcat(query,saveKey); 
    strcat(query,"\r\n"); 
    strcat(query,"\r\n"); 
    printf("%s",query); 


    write(clnt_sock, query, sizeof(query)); 
    close(clnt_sock); 
    close(serv_sock); 
    return 0; 
} 

void error_handling(char *message) 
{ 
    fputs(message, stderr); 
    fputc('\n', stderr); 
    exit(1); 
}`enter code here` 

私の質問を読んでいただきありがとうございます!

+0

問題があるかどうかわかりませんが、書き込みコールは* write(clnt_sock、query、sizeof(char)* strlen(query)); *クエリがchar配列であるためsizeofあなたがおそらく予想しているように、文字列のサイズではなくポインタのサイズ。言い換えれば、文字列全体の代わりに4文字を書く可能性が高いです。 – Corbin

+0

私にコービンを教えてくれてありがとう!しかし、今問題T_Tでした... サーバが応答を送信するときにopOpenがクライアント側で動作しない理由を知る必要があります – nathan

答えて

2

定義された順序でヘッダーを送信するクライアントに頼ることはできません。 parsingHeader [5]の値を取るのではなく、 "Sec-WebSocket-Key"が見つかるまで、parsingHeader内のすべての項目をループする必要があります。

その後、応答するキーを変更する必要があります。 RFC 6455にこれが記載されています。 saveKeyにmagicKeyを追加した後、sha-1ハッシュを取り、base64エンコードしてください。 RFC 3174には、sha-1ハッシュを生成するコードが含まれています。 this oneのように、オープンソースのbase64エンコーダがたくさんあります。

+0

うわー私はあなたを知っていますsimonc!実際に私は握手をした後にあなたの返事を見ましたが、私が見たあなたの他の返信は私に握手を完了させるのです!それは他人の答えでしたが、本当に私を助けてくれてありがとう! :D私は私の質問であなたを見てうれしい!! – nathan

+1

あなたの質問を実際のサンプルコードで更新できますか? :-) – Piranna

関連する問題