atwiki-logo
  • 新規作成
    • 新規ページ作成
    • 新規ページ作成(その他)
      • このページをコピーして新規ページ作成
      • このウィキ内の別ページをコピーして新規ページ作成
      • このページの子ページを作成
    • 新規ウィキ作成
  • 編集
    • ページ編集
    • ページ編集(簡易版)
    • ページ名変更
    • メニュー非表示でページ編集
    • ページの閲覧/編集権限変更
    • ページの編集モード変更
    • このページにファイルをアップロード
    • メニューを編集
    • 右メニューを編集
  • バージョン管理
    • 最新版変更点(差分)
    • 編集履歴(バックアップ)
    • アップロードファイル履歴
    • ページ操作履歴
  • ページ一覧
    • ページ一覧
    • このウィキのタグ一覧
    • このウィキのタグ(更新順)
    • このページの全コメント一覧
    • このウィキの全コメント一覧
    • おまかせページ移動
  • RSS
    • このウィキの更新情報RSS
    • このウィキ新着ページRSS
  • ヘルプ
    • ご利用ガイド
    • Wiki初心者向けガイド(基本操作)
    • このウィキの管理者に連絡
    • 運営会社に連絡(不具合、障害など)
ページ検索 メニュー
frostar@wiki
  • ウィキ募集バナー
  • 目安箱バナー
  • 操作ガイド
  • 新規作成
  • 編集する
  • 全ページ一覧
  • 登録/ログイン
ページ一覧
frostar@wiki
  • ウィキ募集バナー
  • 目安箱バナー
  • 操作ガイド
  • 新規作成
  • 編集する
  • 全ページ一覧
  • 登録/ログイン
ページ一覧
frostar@wiki
ページ検索 メニュー
  • 新規作成
  • 編集する
  • 登録/ログイン
  • 管理メニュー
管理メニュー
  • 新規作成
    • 新規ページ作成
    • 新規ページ作成(その他)
      • このページをコピーして新規ページ作成
      • このウィキ内の別ページをコピーして新規ページ作成
      • このページの子ページを作成
    • 新規ウィキ作成
  • 編集
    • ページ編集
    • ページ編集(簡易版)
    • ページ名変更
    • メニュー非表示でページ編集
    • ページの閲覧/編集権限変更
    • ページの編集モード変更
    • このページにファイルをアップロード
    • メニューを編集
    • 右メニューを編集
  • バージョン管理
    • 最新版変更点(差分)
    • 編集履歴(バックアップ)
    • アップロードファイル履歴
    • ページ操作履歴
  • ページ一覧
    • このウィキの全ページ一覧
    • このウィキのタグ一覧
    • このウィキのタグ一覧(更新順)
    • このページの全コメント一覧
    • このウィキの全コメント一覧
    • おまかせページ移動
  • RSS
    • このwikiの更新情報RSS
    • このwikiの新着ページRSS
  • ヘルプ
    • ご利用ガイド
    • Wiki初心者向けガイド(基本操作)
    • このウィキの管理者に連絡
    • 運営会社に連絡する(不具合、障害など)
  • atwiki
  • frostar@wiki
  • WebSocketサーバ

frostar@wiki

WebSocketサーバ

最終更新:2014年04月01日 20:21

frostar

- view
管理者のみ編集可
ちょっとJavaScriptとやりとりするサーバを作りたいと思ったので
winsockを使ってWebSocketサーバを作成しました。
とりあえず以下は単純なechoサーバです。
クライアント側との接続を確立するためにメッセージを解析して
それにSHA1とBase64という処理をかけたものを返す必要があるのですが、
その2つに関しては省略しています(探せば見つかると思います)。
クライアント側はEchoTestなどを使って試してみてください。
長すぎる文字列には対応してません(124文字くらいまで)。

  1. #include <stdio.h>
  2. #include <winsock2.h>
  3.  
  4. void SHA1(char* pszKey,int key_len,char* hash);//SHA1を返す
  5. void Base64(char* hash,int hash_len,char* sz);//Base64を返す
  6.  
  7. bool HandShake(SOCKET sock);
  8.  
  9. int main(){
  10. WSADATA wsaData;
  11. SOCKET sock0;
  12. struct sockaddr_in addr;
  13. struct sockaddr_in client;
  14. SOCKET sock;
  15. int len;
  16. BOOL yes = 1;
  17.  
  18. char inbuf[4096];
  19.  
  20. if (WSAStartup(MAKEWORD(2,0), &wsaData) != 0) {
  21. return 1;
  22. }
  23.  
  24. sock0 = socket(AF_INET, SOCK_STREAM, 0);
  25. if(sock0 == INVALID_SOCKET) {
  26. printf("socket : %d\n", WSAGetLastError());
  27. return 1;
  28. }
  29.  
  30. addr.sin_family = AF_INET;
  31. addr.sin_port = htons(12345);
  32. addr.sin_addr.S_un.S_addr = INADDR_ANY;
  33. setsockopt(sock0,SOL_SOCKET, SO_REUSEADDR, (const char *)&yes, sizeof(yes));
  34. if (bind(sock0, (struct sockaddr *)&addr, sizeof(addr)) != 0) {
  35. printf("bind : %d\n", WSAGetLastError());
  36. return 1;
  37. }
  38. if (listen(sock0, 5) != 0) {
  39. printf("listen : %d\n", WSAGetLastError());
  40. return 1;
  41. }
  42. bool isHandShaked = false;
  43. while (1) {
  44. len = sizeof(client);
  45. sock = accept(sock0, (struct sockaddr *)&client, &len);
  46. if (sock == INVALID_SOCKET) {
  47. printf("accept : %d\n", WSAGetLastError());
  48. }
  49. //ハンドシェイクを行う
  50. isHandShaked = HandShake(sock);
  51. if(isHandShaked){
  52. while(1){
  53. memset(inbuf, 0, sizeof(inbuf));
  54. int len = recv(sock, inbuf, sizeof(inbuf), 0);
  55. if(len<=0)break;
  56. //マスクを外す
  57. inbuf[1] = inbuf[1]&0x7f;
  58. char mask[4];
  59. for(int i=0;i<4;i++){
  60. mask[i] = inbuf[2+i];
  61. }
  62. for(int i=6;i<len;i++){
  63. inbuf[i-4] = inbuf[i]^mask[(i-6)%4];
  64. }
  65. inbuf[len-4] = '\0';
  66. //echo
  67. send(sock,inbuf,strlen(inbuf),0);
  68. }
  69. printf("SocketClosed\n");
  70. }
  71. closesocket(sock);
  72. }
  73. WSACleanup();
  74. return 0;
  75. }
  76.  
  77. bool HandShake(SOCKET sock){
  78. char inbuf[1024];
  79. memset(inbuf, 0, sizeof(inbuf));
  80. //クライアントハンドシェイクを取得
  81. if(recv(sock, inbuf, sizeof(inbuf), 0)<=0)return false;
  82. printf("ClientHandShake:\n%s",inbuf);
  83. //ハンドシェイクを分割してSec-WebSocket-Keyの値を取得
  84. char *delim = " \r\n";
  85. char *ctx;
  86. char *next = strtok_s(inbuf,delim,&ctx);
  87. char * pszKeyBase;
  88. while(next){
  89. next = strtok_s(NULL, delim, &ctx);
  90. if(strcmp(next,"Sec-WebSocket-Key:")==0){
  91. pszKeyBase = strtok_s(NULL, delim, &ctx);
  92. break;
  93. }
  94. }
  95. char pszKey[1024];
  96. memset(pszKey, 0, sizeof(pszKey));
  97. sprintf_s(pszKey,sizeof(pszKey), "%s%s",
  98. pszKeyBase,"258EAFA5-E914-47DA-95CA-C5AB0DC85B11");
  99. //SHA1
  100. char hash[20];
  101. SHA1(pszKey,strlen(pszKey),hash);
  102. char pszAcceptKey[256];
  103. //BASE64
  104. Base64(hash,20,pszAcceptKey);
  105. //サーバハンドシェイク作成
  106. char pszHeader[1024];
  107. memset(pszHeader, 0, sizeof(pszHeader));
  108. sprintf_s(pszHeader, sizeof(pszHeader),
  109. "HTTP/1.1 101 Switching Protocols\r\n"
  110. "Upgrade: websocket\r\n"
  111. "Connection: Upgrade\r\n"
  112. "Sec-WebSocket-Accept: %s\r\n\r\n",pszAcceptKey);
  113. printf("ServerHandShake:\n%s",pszHeader);
  114. //サーバハンドシェイク送信
  115. send(sock, pszHeader, (int)strlen(pszHeader), 0);
  116. return true;
  117. }
  118.  

ハンドシェイク時に112行目のように"\r\n\r\n"と最後に2つ改行をつける必要があるところに注意してください。
これが1つだけだとうまく接続が確立できません。多すぎてもダメです。
また、接続確立後にechoするときは受け取ったフレームを解析してその中のマスク情報を使って
マスクを外してからフレームを送り返す必要があります(ただし、FireFoxだとマスクがかかったままでも行けました)。
フレームの仕様などについてはRFC6455を参照してください。
「WebSocketサーバ」をウィキ内検索
LINE
シェア
Tweet

[Amazon商品]


frostar@wiki
記事メニュー

メニュー

  • トップページ
  • プロフィール
  • コメント
    • 足跡
    • ツール
    • その他
  • 公開・更新状況について
作ったもの
  • 注意事項
  • TRPG支援ツール
    • SW2.0
      • キャラ管理ツールver2
      • 表出力ツール
      • 抽出ツール
    • でたとこサーガ
      • でたとこツール
    • 永い後日談のネクロニカ
      • キャラ管理ツール
    • その他
      • 2次元戦闘管理ツール
  • LimeChat2用マクロ
    • インストール・設定
    • 直線距離管理ツール
      • Reference
    • HPMPツール
      • Reference
    • 汎用ランダム出力ツール
      • Reference
    • 汎用デッキツール
      • Reference
  • ライブラリ
    • C++
      • ListViewEx

過去の遺物
  • ソフトの配布について
  • お手伝いについて
  • SW2.0
    • キャラ管理ツール
      • FAQ
    • GMツール
    • モンスターツール
  • DX3rd
    • キャラ管理ツール
  • 迷宮キングダム
    • キャラ管理ツール
    • まよきんダイス
  • それ以外
    • ADVスクリプタ
  • 作りたいもの
TRPG
  • コラム
    • コラムについて
    • TRPGとは
    • オンラインセッションについて
    • GM向け
      • GMを始める前に
      • シナリオの作り方
      • マスタリング
  • システム紹介
    • SW2.0
      • 基本ルールブック
      • データ系サプリメント
      • データ系サプリメント2
      • プレイヤーズハンドブック
      • シナリオ系サプリメント
      • ツアー系サプリメント
  • データ
    • SW2.0
      • モンスターデータ
プログラム
  • プログラムを始める人へ
  • プログラムメモ
    • データ構造
      • リスト構造
    • 時間計測
    • FPS管理
    • 数学関数
    • 文字列操作関数
      • strrep
    • 描画関数
      • TransparentAlphaBlt
      • RotateBlt
      • RotateTransparentAlphaBlt
      • 描画関数の時間比較
    • 知っておくと便利
    • コントロール
      • 色を変える
      • チェックボックス付きリストビュー
    • C++標準ライブラリ系
      • StringSplit
      • AccessIterator
      • Java風Iterator
    • winsock系
      • WebSocketサーバ
    • JavaScript系
      • JSONPででたとこのデータ取得
  • CodeIQ
    • 結城浩さんの問題
      • Bits
      • Nick
      • Scissors
    • Paiza Online Hackathon
      • 新人女子の書いたコードを直すやつ
リンク

自分関係

  • リンクについて
ここのページへのリンクについてはこちら
  • ブログ:幾星霜
TRPGのセッション記録とかメインのブログ
  • USTREAM:frostのプログラム雑談室
生配信チャンネル。プログラム<雑談
気が向いたときにやります
  • THE INTERVIEWS
個人的な質問に答えてます。

TRPG系

  • 月光華亭
お世話になっているオンラインセッションサイト
  • TRPG.NET
TRPGのことならここ!
IRCサーバなど、お世話になってます。
  • 屍少女たちの永い午睡(相互)
ネクロニカの支援サイトです。ツール開発やオンセもやっています。

プログラム系

  • 猫でもわかるプログラミング
初心者のためのプログラムのページ。WindowsSDKの方についても詳しく書いています。
  • 窓プログラミング
windowsSDKのテクニックがいろいろ書いてあります。
  • C/C++リファレンス
C++STL(標準テンプレートライブラリ)の日本語版リファレンスです。

@frost_star からのツイート

更新履歴

取得中です。


ここを編集
記事メニュー2
人気記事ランキング
  1. SW2.0キャラ管理ツール
  2. 描画関数の時間比較
  3. まよきんキャラ管理ツール
もっと見る
最近更新されたページ
  • 2016日前

    足跡
  • 3752日前

    JSONPででたとこのデータ取得
  • 3752日前

    メニュー
  • 3757日前

    でたとこサーガ支援ツール
  • 3757日前

    表出力ツール
  • 3758日前

    直線距離管理ツール
  • 3765日前

    直線距離管理ツール:Reference
  • 3765日前

    SW2.0キャラ管理ツールver2
  • 3844日前

    汎用ランダム出力ツール:Reference
  • 3844日前

    汎用デッキツール
もっと見る
人気記事ランキング
  1. SW2.0キャラ管理ツール
  2. 描画関数の時間比較
  3. まよきんキャラ管理ツール
もっと見る
最近更新されたページ
  • 2016日前

    足跡
  • 3752日前

    JSONPででたとこのデータ取得
  • 3752日前

    メニュー
  • 3757日前

    でたとこサーガ支援ツール
  • 3757日前

    表出力ツール
  • 3758日前

    直線距離管理ツール
  • 3765日前

    直線距離管理ツール:Reference
  • 3765日前

    SW2.0キャラ管理ツールver2
  • 3844日前

    汎用ランダム出力ツール:Reference
  • 3844日前

    汎用デッキツール
もっと見る
ウィキ募集バナー
新規Wikiランキング

最近作成されたWikiのアクセスランキングです。見るだけでなく加筆してみよう!

  1. 鹿乃つの氏 周辺注意喚起@ウィキ
  2. 機動戦士ガンダム EXTREME VS.2 INFINITEBOOST wiki
  3. MadTown GTA (Beta) まとめウィキ
  4. R.E.P.O. 日本語解説Wiki
  5. シュガードール情報まとめウィキ
  6. ソードランページ @ 非公式wiki
  7. AviUtl2のWiki
  8. Dark War Survival攻略
  9. シミュグラ2Wiki(Simulation Of Grand2)GTARP
  10. 星飼いの詩@ ウィキ
もっと見る
人気Wikiランキング

atwikiでよく見られているWikiのランキングです。新しい情報を発見してみよう!

  1. アニヲタWiki(仮)
  2. ストグラ まとめ @ウィキ
  3. ゲームカタログ@Wiki ~名作からクソゲーまで~
  4. 初音ミク Wiki
  5. 発車メロディーwiki
  6. 検索してはいけない言葉 @ ウィキ
  7. モンスター烈伝オレカバトル2@wiki
  8. 機動戦士ガンダム バトルオペレーション2攻略Wiki 3rd Season
  9. Grand Theft Auto V(グランドセフトオート5)GTA5 & GTAオンライン 情報・攻略wiki
  10. パタポン2 ドンチャカ♪@うぃき
もっと見る
全体ページランキング

最近アクセスの多かったページランキングです。話題のページを見に行こう!

  1. 参加者一覧 - ストグラ まとめ @ウィキ
  2. Trickster - ストグラ まとめ @ウィキ
  3. 暦家 - ストグラ まとめ @ウィキ
  4. 魔獣トゲイラ - バトルロイヤルR+α ファンフィクション(二次創作など)総合wiki
  5. hantasma - ストグラ まとめ @ウィキ
  6. ギャング - ストグラ まとめ @ウィキ
  7. スーパーマン(2025年の映画) - アニヲタWiki(仮)
  8. RqteL - ストグラ まとめ @ウィキ
  9. 機体一覧 - 機動戦士ガンダム EXTREME VS.2 INFINITEBOOST wiki
  10. 過去の行動&発言まとめ - 鹿乃つの氏 周辺注意喚起@ウィキ
もっと見る

  • このWikiのTOPへ
  • 全ページ一覧
  • アットウィキTOP
  • 利用規約
  • プライバシーポリシー

2019 AtWiki, Inc.