private bool flush(int timeout) { int len = 0; while ((len < writeIndex) && ((timeout < 0) || (timer.ElapsedMilliseconds < timeout))) { int t = -1; if (timeout >= 0) { t = timeout - (int)timer.ElapsedMilliseconds; if (t < 0) { t = 0; } } if (Soc.Poll(t * 1000, SelectMode.SelectWrite)) { int l = Soc.Send(writeBuf, len, writeIndex - len, SocketFlags.None); if (l <= 0) { throw new SocketException(SocError.NO_RECOVERY); } len += l; } } writeIndex -= len; if (writeIndex < 0) { writeIndex = 0; // Fail safe. } return(writeIndex == 0); }
/// <summary> /// ソケットから複数バイトを読む /// </summary> /// <remarks> /// <para> /// ソケットの切断などのエラーが発生した場合は、SocketExceptionがthrow /// される。 /// </para> /// </remarks> /// <param name="buf">読み取ったデータを格納する配列</param> /// <param name="offset">読み取ったデータを格納する先頭位置</param> /// <param name="size">読み取りバイト数</param> /// <param name="timeout">最大待ち時間(ミリ秒)</param> /// <returns>読みとったバイト数。sizeと等しくない場合はタイムアウトが発生した。</returns> public int Read(byte[] buf, int offset, int size, int timeout) { if (Soc == null) { throw new SocketException(SocError.ENOTCONN); } if (timeout == 0) { // すぐに読める分だけ読む int sz = Soc.Available; if (size < sz) { sz = size; } if (sz > 0) { return(Soc.Receive(buf, offset, sz, SocketFlags.None)); } else { return(0); } } timer.Reset(); timer.Start(); int len = 0; while ((len < size) && ((timeout < 0) || (timer.ElapsedMilliseconds < timeout))) { int t = -1; if (timeout >= 0) { t = timeout - (int)timer.ElapsedMilliseconds; if (t < 0) { t = 0; } } if (Soc.Poll(t * 1000, SelectMode.SelectRead)) { int sz = Soc.Available; if (size - len < sz) { sz = size - len; } int l = Soc.Receive(buf, offset + len, sz, SocketFlags.None); if (l <= 0) { throw new SocketException(SocError.NO_DATA); } len += l; } } timer.Stop(); return(len); }
/// <summary> /// クライアントからの接続を待ち、通信用ソケットを新たに作成する。 /// </summary> /// <remarks> /// <para> /// タイムアウト以外の接続失敗が発生すると、SocketExceptionが発生する。 /// </para> /// </remarks> /// <param name="timeout">最大待ち時間(ミリ秒)負の値を指定すると無限に待つ。</param> /// <param name="crtfile">サーバ認証CRTファイル名。nullの場合SSL接続せずに単純なTCPソケット接続を行なう。</param> /// <returns>新たな通信用ソケット。タイムアウト時はnull</returns> public SocStream Accept(int timeout = -1, string crtfile = null) { if (Soc == null) { throw new SocketException(SocError.ENOTCONN); } if (!Soc.Poll(timeout * 1000, SelectMode.SelectRead)) { return(null); } Socket s = Soc.Accept(); return(new SocStream(s, crtfile)); }
/// <summary> /// ソケットから1バイト読む /// </summary> /// <remarks> /// <para> /// ソケットの切断などのエラーが発生した場合は、SocketExceptionがthrow /// される。 /// </para> /// </remarks> /// <param name="res">読み取ったデータを格納する変数</param> /// <param name="timeout">タイムアウト時間(ミリ秒)</param> /// <returns>true=読み取り成功, false=タイムアウト</returns> public bool ReadOne(out byte res, int timeout) { if (Soc == null) { throw new SocketException(SocError.ENOTCONN); } if (!Soc.Poll(timeout * 1000, SelectMode.SelectRead)) { res = 0; return(false); } byte[] buf = new byte[1]; if (Soc.Receive(buf, 0, 1, SocketFlags.None) != 1) { throw new SocketException(SocError.NO_DATA); } res = buf[0]; return(true); }