これの実装用に作った,socketをstreamでラップしたC++用のライブラリです.
ビックエンディアンかリトルエンディアンの環境なら,バイトオーダを気にせず通信可能です.
開発中のバージョンなので,バグとか変な仕様とかたくさんあると思います.
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;
}
ライブラリの作者本人は,これから,このライブラリを使ってプログラムを作ろうとしています.
まだ,テストが済んでいないも同然なので,使う時は気をつけてください^^;
私好みの仕様の部分が多いので,iostream全般で共通のルール等が通用しない気がします.
エラー処理がいい加減です.
iostreamっぽく,バイトオーダの違いを無視して通信ができます.
socketプログラミングの,おまじないや慣用句のコピペが減るかもしれません.
cin, coutさえ使った事があれば,ネットワークプログラミングができるかもしれません.
VC++8, gcc3.4.4(cygwin, FreeBSD), gcc4.0.0(MacOS X)で動作するようです.
バイトオーダの異なる環境同士でも通信可能です.
バグがあった時にライブラリを疑う気持ち.
iostreamのsocket版.バイトオーダの解決をした上で送受信してくれます.
int等の整数型はバイナリの状態で送られるので,帯域が節約できたり.
outs << 10 << "0:hoge";
を
ins >> int_value >> str;
で拾った時に,"100:hoge"の文字列が送られるせいで
outs == 100 str == ":hoge"
になる心配が無くて幸せ.
telnetやHTTPクライアントを作りたい場合は,socketstreamを使わず
iostreamにsocketstreambufを食わせれば,ただのテキストとして送れます.
名前の長いクラス.socket用streambuf.
自前実装->filebufのサブクラス->自前実装
と変化しました.
fdopen後のソケットの挙動が,WindowsとUnixで違うのが気になったので,filebufは使うのをやめました...
今度再挑戦?
自分のマシン以外で動作する事を確認していないので,動作確認をしていただけると嬉しいです.
ご自由にお使いください.
バグを見つけたら報告をいただけると嬉しいです.直していただけるともっと嬉しいです.
教えていただけたら,なるべく直すように努力しますが,興味が失せていると直さないと思います.
もちろん連絡をいただけたら,大喜びします.
すごくいい加減なサンプルコード.ポート番号10000番決め打ちの物3つ.
#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;
}
#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;
}