Japanesegimite/socket○概要TCP/IPとUDP/IPの通信をするためのC++ライブラリです。Socketを使用)に対応しています。Ver.1.5○注意Ver.1.1からserver_socketがserver_stream_socketに変わり、仕様もちょっと変わりました。Windowsのヘッダによっては、内部でWinsock.hをincludeしてしまい、コンパイルエラーの原因になるものが有ります。先にWinsock2.hをincludeすれば回避できると思います。2.9xでは、streambufの形式が古いので使えません。STLPort使えばいいのかも?リファレンス内で、よく使うメンバには★が付いています。○例socket_streamを使えば、ストリームソケットをC++のiostreamとして扱えます。main(){//最初に1回だけ呼び出してください。gimite::startup_socket();{//www.google.comのポート80(HTTP)に接続。80);//エラーチェック。std::endl;}else{//文字列を送信。s;//1行ずつ受信して表示。std::endl;}}//最後に1回だけ呼び出してください。0;}server_stream_socketはサーバ側ストリームソケットをラップしています。main(){//最初に1回だけ呼び出してください。gimite::startup_socket();{//ポート12345でクライアントの接続を受け付け始めます。server(12345);//エラーチェック。(true){//クライアントからの接続要求を待ち、最初に来た人との//通信のためのソケットハンドルを返します。server.accept();//クライアントと通信するためのsocket_streamを作成。sst(s);//ここでは、受信した文字列をオウム返ししています。c;}}}//最後に1回だけ呼び出してください。0;}datagram_socketはデータグラムソケットをラップしています。main(){//最初に1回だけ呼び出してください。saddr;//ポート12345にソケットを作成。(true){//5バイトのパケットを受信。送信者のアドレスがsaddrに入ります。&saddr);//受け取った文字列を表示。std::endl;//返事のパケット"pong\0"を送信。&saddr);}}//最後に1回だけ呼び出してください。main(){//最初に1回だけ呼び出してください。gimite::startup_socket();{//送信先アドレスはlocahostのポート12345。12345);//ポート番号はおまかせでソケットを作成。dsock(0);//パケット"ping\0"を送信。cs[5];//5バイトのパケットを受信。5);//受け取った文字列を表示。std::endl;}//最後に1回だけ呼び出してください。★★ソケットシステムの初期化をする。最初に1度呼び出してください。成功すればtrue、失敗すればfalseを返す。startup_socket()を2回以上呼んでも構いませんが、同じ数だけcleanup_socket()を呼ぶ必要が有ります。★★ソケットシステムの後始末をする。最後に1度呼び出してください。○socket_streamストリームソケット(TCP)のラッパ。std::iostreamを継承しているので、std::iostreamの入出力機能を使って送受信できる。あとでopen()を呼び出す事で接続できる。★★サーバに接続する。hostがサーバのホスト名orIPアドレス。portがサーバのポート番号。sock);既存のソケットハンドル(::socket()の戻り値など)をsocket_streamに割り当てる。ソケットハンドルはsocket_streamのデストラクタでクローズされるので注意。これを避けるにはrelease()を使う。~socket_stream();サーバから切断する。hostがサーバのホスト名orIPアドレス。portがサーバのポート番号。close();サーバから切断する。他のスレッドからclose()を呼ぶ事で、受信待ちのブロック状態を終わらせる事が可能。release();ソケットハンドルをクローズせずに、socket_streamの管理から解放する。size);bufferからsizeバイトを送信する。生のAPIに近い方法。機能的にはostream::write()などを使うと同じ。送信したバイト数を返す。エラーなら-1を返す。size);bufferに最大sizeバイトを受信する。生のAPIに近い方法。1バイト以上受信していれば、sizeバイトに達しなくても、受信したデータを返す。この点がistream::read()などとは異なる。受信したバイト数を返す。エラーなら-1を返す。socket()const;ソケットハンドルを返す。接続されている時、socket_streamをbool型の文脈(if文など)で評価するとtrueを返す。*1ただ、そもそもsocket_streamはスレッド安全性を考えてないので、この方法の安全性も怪しいです(汗)。○server_stream_socketサーバ側ストリームソケット(TCP)のラッパ。★バインドを行わない。あとでbind()を呼び出す事でバインドできる。★★ソケットを作り、バインドしてListen状態にする。portがポート番号。backlogが接続要求を溜めるキューの大きさ。is_bound);既存のソケットハンドルをserver_stream_socketに割り当てる。ソケットハンドルがバインド済みのものかどうかをis_boundに指定する。~server_stream_socket();ソケットをクローズする。★ソケットを作り、バインドしてListen状態にする。portがポート番号。backlogが接続要求を溜めるキューの大きさ。成功するとtrue、失敗するとfalseを返す。失敗した場合は、続けて他のポートへのbind()を試す事ができる。★★クライアントからの接続要求を1個受け入れる。ソケットハンドル(::accept()の戻り値)を返す。close();ソケットをクローズする。release();ソケットハンドルをクローズせずに、server_stream_socketの管理から解放する。is_bound);既存のソケットハンドルをserver_stream_socketに割り当てる。ソケットハンドルがバインド済みのものかどうかをis_boundに指定する。socket()const;ソケットハンドルを返す。バインドされている時、server_stream_socketをbool型の文脈(if文など)で評価するとtrueを返す。○datagram_socketデータグラムソケット(UDP)のラッパ。★バインドを行わない。あとでbind()を呼び出す事でバインドできる。★★ソケットを作り、バインドする。portがポート番号。is_bound);既存のソケットハンドルをdatagram_socketに割り当てる。ソケットハンドルがバインド済みのものかどうかをis_boundに指定する。~datagram_socket();ソケットをクローズする。★ソケットを作り、バインドしてListen状態にする。portがポート番号。0を指定すると、自動で割り当てる。成功するとtrue、失敗するとfalseを返す。失敗した場合は、続けて他のポートへのbind()を試す事ができる。★★パケットを受信する。受信したパケットはbufferからsizeバイトに書き込まれる。addrが0以外なら、*addrに送信者のアドレスが書き込まれる。flagsは拡張フラグ。::recvfrom()にそのまま渡される。★★パケットを送信する。bufferからsizeバイトを*addrに送信する。flagsは拡張フラグ。::sendto()にそのまま渡される。close();ソケットをクローズする。release();ソケットハンドルをクローズせずに、datagram_socketの管理から解放する。is_bound);既存のソケットハンドルをdatagram_socketに割り当てる。ソケットハンドルがバインド済みのものかどうかをis_boundに指定する。socket()const;ソケットハンドルを返す。バインドされている時、datagram_socketをbool型の文脈(if文など)で評価するとtrueを返す。○ip_addressIPアドレスを表すクラス。ip_addressの代わりに、std::stringやchar*を渡してもOK(例:socket_streamのコンストラクタの引数)。INADDR_NONE);IPアドレスを32ビット整数で指定する。host);ホスト名("www.google.co.jp"など)かピリオドで区切ったIPアドレス("127.0.0.1"など)を指定する。addr()const;IPアドレスを表すin_addr構造体を返す。as_int()const;IPアドレスを表す32ビット整数を返す。○socket_addressIPアドレスとポート番号の組を表す構造体。★IPアドレスとポート番号を指定して初期化する。port;ポート番号。生のSocket関数群がソケットを区別するために使うハンドル。IPアドレスを表す32ビット符号無し整数。diagram_socketをdatagram_socketに改名。ip_address、socket_addressに対して「大小と等値の比較」と「ostreamへの出力」ができるように。'\xff'を受信するとEOFとみなしてしまう場合が有ったのを修正。socket_stream::send()とsocket_stream::recv()を追加。server_socketをserver_stream_socketに改名してちょっと仕様変更。diagram_socketを追加。ホスト名を直接指定する代わりにip_addressクラスを使うように(文字列からip_addressへの暗黙の型変換が定義されているので、今までの書き方も通る)。socket_streamを高速化(したつもり)。3.3(FreeBSD)で動作確認しました。他の環境での動作確認や、「ここを直したら動いた」などの報告は掲示板にどうぞ。