//送信 bool Send(TcpObj sock, byte[] sendBuf) { int c = sock.SendUseEncode(sendBuf); if (c == sendBuf.Length) { sendBuf = new byte[0]; } else { return(false); } return(true); }
void callBack(IAsyncResult ar) { //接続完了(Listenソケットを取得) SockObj sockObj = (SockObj)(ar.AsyncState); //接続ソケットを保持して tcpObj = (TcpObj)sockObj.CreateChildObj(ar); //Listenソケットをクローズする sockObj.Close(); //パイプスレッドの生成 t = new Thread(new ThreadStart(Pipe)); t.IsBackground = true; t.Start(); }
//バッファに残っているデータの送信 //パラメータ cs CS.SERVER を設定した場合、buf[CS.SERVER]を処理対象とし、クライアント側に送信する bool SendBuf(CS cs) { TcpObj sock = proxy.Sock(CS.CLIENT); if (cs == CS.CLIENT) { sock = proxy.Sock(CS.SERVER); } int len = oneObj.Buf[cs].Length - oneObj.Pos[cs]; if (len > 0) { byte[] sendBuf = new byte[len]; Buffer.BlockCopy(oneObj.Buf[cs], oneObj.Pos[cs], sendBuf, 0, len); if (!Send(sock, sendBuf))//送信 { return(false); } oneObj.Pos[cs] += len; } return(true); }
public Http(TcpObj clientSocket) { sock[CS.CLIENT] = clientSocket; sock[CS.SERVER] = null; }
//送信 bool Send(TcpObj sock,byte[] sendBuf) { int c = sock.SendUseEncode(sendBuf); if(c == sendBuf.Length) { sendBuf = new byte[0]; } else { return false; } return true; }
public DataThread(Logger logger, TcpObj listenObj) { this.logger = logger; listenObj.StartServer(new AsyncCallback(callBack)); }
//*************************************************************** // パイプ(FTP) //*************************************************************** int PipeFtp(Dictionary<CS, TcpObj> sock, Request request,int dataPort) { DataThread dataThread = null; //ユーザ名及びパスワード string user = "******"; string pass = this.OpBase.ValString("anonymousAddress"); //Ver5.0.0-a23 URLで指定されたユーザ名およびパスワードを使用する if(request.User != null) user = request.User; if(request.Pass != null) pass = request.Pass; //wait 220 welcome if(!WaitLine(sock,"220")) goto end; sock[CS.SERVER].AsciiSend(string.Format("USER {0}",user),OPERATE_CRLF.YES); if(!WaitLine(sock,"331")) goto end; sock[CS.SERVER].AsciiSend(string.Format("PASS {0}",pass),OPERATE_CRLF.YES); if(!WaitLine(sock,"230")) goto end; //URIをパスとファイル名に分解する string path = request.Uri; string file = ""; int index = request.Uri.LastIndexOf('/'); if (index < request.Uri.Length - 1) { path = request.Uri.Substring(0, index); file = request.Uri.Substring(index + 1); } //リクエスト if (path != "") { sock[CS.SERVER].AsciiSend(string.Format("CWD {0}",path),OPERATE_CRLF.YES); if (!WaitLine(sock, "250")) goto end; } if (file == "") { sock[CS.SERVER].AsciiSend("TYPE A",OPERATE_CRLF.YES); } else { sock[CS.SERVER].AsciiSend("TYPE I",OPERATE_CRLF.YES); } if(!WaitLine(sock,"200")) goto end; //PORTコマンド送信 Ip bindAddr = new Ip(sock[CS.SERVER].LocalEndPoint.Address.ToString()); // 利用可能なデータポートの選定 int listenMax = 1; SSL ssl = null; TcpObj listenObj=null; while(life){ listenObj = new TcpObj(kanel, this.Logger,bindAddr, dataPort++, listenMax, ssl); if (listenObj.State != SOCKET_OBJ_STATE.ERROR) break; } if(listenObj==null) goto end; //データスレッドの生成 dataThread = new DataThread(this.Logger, listenObj); // サーバ側に送るPORTコマンドを生成する string str = string.Format("PORT {0},{1},{2},{3},{4},{5}",bindAddr.IpV4[0],bindAddr.IpV4[1],bindAddr.IpV4[2],bindAddr.IpV4[3],(listenObj.LocalEndPoint.Port) / 256,(listenObj.LocalEndPoint.Port) % 256); sock[CS.SERVER].AsciiSend(str,OPERATE_CRLF.YES); if(!WaitLine(sock,"200")) goto end; if(file==""){ sock[CS.SERVER].AsciiSend("LIST",OPERATE_CRLF.YES); if(!WaitLine(sock,"150")) goto end; }else{ sock[CS.SERVER].AsciiSend("RETR " + file,OPERATE_CRLF.YES); if(!WaitLine(sock,"150")) goto end; } if(!WaitLine(sock,"226")) goto end; byte[] doc = new byte[0]; if (file == "") { //受信結果をデータスレッドから取得する List<string> lines = Inet.GetLines(dataThread.ToString()); //FTPサーバから取得したLISTの情報をHTMLにコンバートする doc = ConvFtpList(lines, path); } else { doc = dataThread.ToBytes(); } //クライアントへリプライ及びヘッダを送信する Header header = new Header(); header.Replace("Server",Util.SwapStr("$v",kanel.Ver.Version(),this.OpBase.ValString("serverHeader"))); header.Replace("MIME-Version","1.0"); if (file == "") { header.Replace("Date",Util.UtcTime2Str(DateTime.UtcNow)); header.Replace("Content-Type","text/html"); } else { header.Replace("Content-Type","none/none"); } header.Replace("Content-Length",doc.Length.ToString()); sock[CS.CLIENT].AsciiSend("HTTP/1.0 200 OK",OPERATE_CRLF.YES);//リプライ送信 sock[CS.CLIENT].Send(header.GetBytes());//ヘッダ送信 sock[CS.CLIENT].Send(doc);//ボディ送信 end: if (dataThread != null) dataThread.Dispose(); return dataPort; }
//*************************************************************** // パイプ(FTP) //*************************************************************** int PipeFtp(Dictionary <CS, TcpObj> sock, Request request, int dataPort) { DataThread dataThread = null; //ユーザ名及びパスワード string user = "******"; string pass = this.OpBase.ValString("anonymousAddress"); //Ver5.0.0-a23 URLで指定されたユーザ名およびパスワードを使用する if (request.User != null) { user = request.User; } if (request.Pass != null) { pass = request.Pass; } //wait 220 welcome if (!WaitLine(sock, "220")) { goto end; } sock[CS.SERVER].AsciiSend(string.Format("USER {0}", user), OPERATE_CRLF.YES); if (!WaitLine(sock, "331")) { goto end; } sock[CS.SERVER].AsciiSend(string.Format("PASS {0}", pass), OPERATE_CRLF.YES); if (!WaitLine(sock, "230")) { goto end; } //URIをパスとファイル名に分解する string path = request.Uri; string file = ""; int index = request.Uri.LastIndexOf('/'); if (index < request.Uri.Length - 1) { path = request.Uri.Substring(0, index); file = request.Uri.Substring(index + 1); } //リクエスト if (path != "") { sock[CS.SERVER].AsciiSend(string.Format("CWD {0}", path), OPERATE_CRLF.YES); if (!WaitLine(sock, "250")) { goto end; } } if (file == "") { sock[CS.SERVER].AsciiSend("TYPE A", OPERATE_CRLF.YES); } else { sock[CS.SERVER].AsciiSend("TYPE I", OPERATE_CRLF.YES); } if (!WaitLine(sock, "200")) { goto end; } //PORTコマンド送信 Ip bindAddr = new Ip(sock[CS.SERVER].LocalEndPoint.Address.ToString()); // 利用可能なデータポートの選定 int listenMax = 1; SSL ssl = null; TcpObj listenObj = null; while (life) { listenObj = new TcpObj(kanel, this.Logger, bindAddr, dataPort++, listenMax, ssl); if (listenObj.State != SOCKET_OBJ_STATE.ERROR) { break; } } if (listenObj == null) { goto end; } //データスレッドの生成 dataThread = new DataThread(this.Logger, listenObj); // サーバ側に送るPORTコマンドを生成する string str = string.Format("PORT {0},{1},{2},{3},{4},{5}", bindAddr.IpV4[0], bindAddr.IpV4[1], bindAddr.IpV4[2], bindAddr.IpV4[3], (listenObj.LocalEndPoint.Port) / 256, (listenObj.LocalEndPoint.Port) % 256); sock[CS.SERVER].AsciiSend(str, OPERATE_CRLF.YES); if (!WaitLine(sock, "200")) { goto end; } if (file == "") { sock[CS.SERVER].AsciiSend("LIST", OPERATE_CRLF.YES); if (!WaitLine(sock, "150")) { goto end; } } else { sock[CS.SERVER].AsciiSend("RETR " + file, OPERATE_CRLF.YES); if (!WaitLine(sock, "150")) { goto end; } } if (!WaitLine(sock, "226")) { goto end; } byte[] doc = new byte[0]; if (file == "") { //受信結果をデータスレッドから取得する List <string> lines = Inet.GetLines(dataThread.ToString()); //FTPサーバから取得したLISTの情報をHTMLにコンバートする doc = ConvFtpList(lines, path); } else { doc = dataThread.ToBytes(); } //クライアントへリプライ及びヘッダを送信する Header header = new Header(); header.Replace("Server", Util.SwapStr("$v", kanel.Ver.Version(), this.OpBase.ValString("serverHeader"))); header.Replace("MIME-Version", "1.0"); if (file == "") { header.Replace("Date", Util.UtcTime2Str(DateTime.UtcNow)); header.Replace("Content-Type", "text/html"); } else { header.Replace("Content-Type", "none/none"); } header.Replace("Content-Length", doc.Length.ToString()); sock[CS.CLIENT].AsciiSend("HTTP/1.0 200 OK", OPERATE_CRLF.YES); //リプライ送信 sock[CS.CLIENT].Send(header.GetBytes()); //ヘッダ送信 sock[CS.CLIENT].Send(doc); //ボディ送信 end: if (dataThread != null) { dataThread.Dispose(); } return(dataPort); }