これの実装用に作った,socketをstreamでラップしたC++用のライブラリです.
ビックエンディアンかリトルエンディアンの環境なら,バイトオーダを気にせず通信可能です.
開発中のバージョンなので,バグとか変な仕様とかたくさんあると思います.

自分用メモ

  • TODO
    • 多分する
      • 効率の為にバッファリングするように.
        他にも色々効率的に怪しいところを...
      • 不動小数点型を使えるように
        こんなのを入れとけば,一応使えるはずですが
        inline float changeByteOrder(const float&v)
        {
            __int32 tmp=ChangeByteOrder<__int32>(*(__int32*)&v);
            return *(float*)&tmp;
        }
        inline double changeByteOrder(const double&v)
        {
            __int64 tmp=ChangeByteOrder<__int64>(*(__int64*)&v);
            return *(double*)&tmp;
        }
        
      • pollの実装をいじる
        Windowsで作ってるのでpollをselectで実装しています...
        まともにPOSIXを実装してる環境向けに,pollでの実装もする.
      • まともなアプリケーションを組んでみる
        テストしないとね...
    • streambufをfilebufで実装しなおし
      自前実装は,色々な所がいい加減です.
      filebufの実装は,きっと素敵なはず.
    • 多分しない
      • 暗号化
        ここの人達から,しろって言われそうだけど...

注意

ライブラリの作者本人は,これから,このライブラリを使ってプログラムを作ろうとしています.
まだ,テストが済んでいないも同然なので,使う時は気をつけてください^^;

私好みの仕様の部分が多いので,iostream全般で共通のルール等が通用しない気がします.

エラー処理がいい加減です.

何ができる?

iostreamっぽく,バイトオーダの違いを無視して通信ができます.

socketプログラミングの,おまじないや慣用句のコピペが減るかもしれません.
cin, coutさえ使った事があれば,ネットワークプログラミングができるかもしれません.

  • iostream好き,read,write嫌いだけど,socketが使いたい
  • PoworPCなMacと簡単に通信したい
    等の要求に多少答えられる気がします

必要な環境

VC++8, gcc3.4.4(cygwin, FreeBSD), gcc4.0.0(MacOS X)で動作するようです.
バイトオーダの異なる環境同士でも通信可能です.

バグがあった時にライブラリを疑う気持ち.

構成

socketstream

iostreamのsocket版.バイトオーダの解決をした上で送受信してくれます.
int等の整数型はバイナリの状態で送られるので,帯域が節約できたり.

outs << 10 << "0:hoge";

ins  >> int_value >> str;

で拾った時に,"100:hoge"の文字列が送られるせいで

 outs == 100
 str  == ":hoge"

になる心配が無くて幸せ.

telnetやHTTPクライアントを作りたい場合は,socketstreamを使わず
iostreamにsocketstreambufを食わせれば,ただのテキストとして送れます.

socketstreambuf

名前の長いクラス.socket用streambuf.
自前実装->filebufのサブクラス->自前実装
と変化しました.
fdopen後のソケットの挙動が,WindowsとUnixで違うのが気になったので,filebufは使うのをやめました...
今度再挑戦?

動作確認

自分のマシン以外で動作する事を確認していないので,動作確認をしていただけると嬉しいです.

ライセンス

ご自由にお使いください.
バグを見つけたら報告をいただけると嬉しいです.直していただけるともっと嬉しいです.
教えていただけたら,なるべく直すように努力しますが,興味が失せていると直さないと思います.

もちろん連絡をいただけたら,大喜びします.

ダウンロード

サンプルコード

すごくいい加減なサンプルコード.ポート番号10000番決め打ちの物3つ.

  • チャット的な物
    交互に発言できるチャット的な物.
    何番目の発言かを管理する為に整数を一緒に送る.
    整数(変数d)は文字列ではなく,数字のまま送られる所がポイント?
    • 待ち受け側
      #include "socketstream.h"
      #include <iostream>
      #include <string>
      
      using namespace std;
      
      int main(int argc, char**argv)
      {
          cout << "byte_order:"<<BYTE_ORDER<<endl;
          socketlistener ltn(10000);
          socketstream socks(ltn.accept());
      
          if(socks.fail())
          {
              cerr << "accept error" << endl;
              return 1; // error
          }
      
          string buf;
          int d=0;
          while(!socks.fail())
          {
              socks >> d >> buf;
              if(socks.fail())
                  break;
              cout << d << ":" << buf << endl;
              cin >> buf;
              d++;
              socks << d << buf;
          }
          socks.close();
          return 0;
      }
      
    • 接続側
      #include "socketstream.h"
      #include <iostream>
      #include <string>
      
      using namespace std;
      
      int main(int argc, char**argv)
      {
          cout << "byte_order:"<<BYTE_ORDER<<endl;
      
          socketconnecter con("localhost", 10000);
          socketstream socks(con.connect());
      
          if(socks.fail())
          {
              cerr << "connect error"<<endl;
              return 1;
          }
          
          string buf;
          int d=0;
          while(!socks.fail())
          {
              cin >> buf;
              socks << d << buf;
      
              socks >> d >> buf;
              if(socks.fail())
                  break;
              cout << d << ":" << buf << endl;
              d++;
          }
          socks.close();
          return 0;
      }
      
  • telnet的な物
    これも交互にしか発言できない...
    socketstreambufをiostreamに食わせる例.
    全ての値は文字列として送られるので,HTTPプロトコル等の実装に使えるかも.
    #include "socketstream.h"
    #include <iostream>
    #include <string>
    
    using namespace std;
    
    int main(int argc, char**argv)
    {
        socketconnecter con("localhost", 10000);
        socketstreambuf ssb(con.connect());
        if(ssb.error())
        {
            cerr << "accept error"<<endl;
            return 1;
        }
    
        iostream ss(&ssb);
    
        string buf;
        while(!cin.eof())
        {
            cin   >> buf;
            ss << buf << endl;
    
            ss >> buf;
            if(!ss.good())
                break;
            cout  << buf << endl;
        }
        ssb.close();
        return 0;
    }
    
  • pollを使ったサンプル
    が無いのは問題だと思う.
    一応使えるはずです.

履歴

  • 2007-10-09
    いらない部分を消した
  • 2007-09-27
    手元に新しいものがあったのでUP
  • 2007-04-02
    float, doubleにいい加減な対応.
    failbitの立て忘れ.
  • 2007-04-02
    初版公開.

コメント


お名前:
添付ファイル: filesocketstream.cpp 1722件 [詳細] filesocketstream.h 3058件 [詳細]