public void Echoサーバにsendしてlength分ずつRecvする() { //setUp const string addr = "127.0.0.1"; const int port = 53; var echoServer = new EchoServer(addr, port); echoServer.Start(); const int timeout = 3; const int max = 1500; const int loop = 10; var tmp = new byte[max]; for (int i = 0; i < max; i++){ tmp[i] = (byte) i; } var ip = new Ip(addr); for (var i = 0; i < loop; i++){ var sockUdp = new SockUdp(new Kernel(), ip, port, null, tmp); // while (sockUdp.Length() == 0){ // Thread.Sleep(10); // } var b = sockUdp.Recv(timeout); //verify for (var m = 0; m < max; m += 10){ Assert.That(b[m], Is.EqualTo(tmp[m])); //送信したデータと受信したデータが同一かどうかのテスト } sockUdp.Close(); } //TearDown echoServer.Stop(); }
public void OneServerを継承したEchoServer_UDP版_を使用して接続する() { const string addr = "127.0.0.1"; const int port = 9991; const int timeout = 300; Ip ip = null; try{ ip = new Ip(addr); } catch (ValidObjException ex){ Assert.Fail(ex.Message); } var oneBind = new OneBind(ip, ProtocolKind.Udp); var conf = TestUtil.CreateConf("OptionSample"); conf.Set("port", port); conf.Set("multiple", 10); conf.Set("acl", new Dat(new CtrlType[0])); conf.Set("enableAcl", 1); conf.Set("timeOut", timeout); var echoServer = new EchoServer(conf, oneBind); echoServer.Start(); //TCPクライアント const int max = 1600; var buf = new byte[max]; buf[8] = 100; //CheckData for (int i = 0; i < 3; i++){ var sockUdp = new SockUdp(new Kernel(), ip, port, null, buf); var b = sockUdp.Recv(timeout); Assert.That(b[8], Is.EqualTo(buf[8])); //CheckData Assert.That(max, Is.EqualTo(b.Length)); sockUdp.Close(); } echoServer.Dispose(); }
// 共通メソッド // リクエスト送信して、サーバから返ったデータをDNSパケットとしてデコードする // レスポンスが無い場合は、1秒でタイムアウトしてnullを返す // rd = 再帰要求 private PacketDns lookup(DnsType dnsType, string name,bool rd=false) { //乱数で識別子生成 var id = (ushort) (new Random()).Next(100); //送信パケット生成 var sp = new PacketDns(id, false, false, rd, false); //質問フィールド追加 sp.AddRr(RrKind.QD, new RrQuery(name, dnsType)); //クライアントソケット生成、及び送信 var cl = new SockUdp(new Kernel(), new Ip(IpKind.V4Localhost), 53, null, sp.GetBytes()); //受信 //byte[] recvBuf = cl.Recv(1000); var recvBuf = cl.Recv(3); if (recvBuf.Length == 0){ //受信データが無い場合 return null; } //System.out.println(string.Format("lookup(%s,\"%s\") recv().Length=%d", dnsType, name, recvBuf.Length)); //デコード var p = new PacketDns(recvBuf); //System.out.println(print(p)); return p; }
//addrは通常オーダで指定されている //private PacketDns Lookup(Ip ip, string requestName, DNS_TYPE dnsType,RemoteInfo remoteInfo) { private PacketDns Lookup(Ip ip, string requestName, DnsType dnsType, Ip remoteAddr) { //Ip ip = new Ip(addr); Logger.Set(LogKind.Detail, null, 17, string.Format("{0} Server={1} Type={2}", requestName, ip, dnsType)); //"Lookup" //受信タイムアウト const int timeout = 3; // var random = new Random(Environment.TickCount); // var id = (ushort) random.Next(0xFFFF);//識別子をランダムに決定する var random = new Random(); var id = (ushort) random.Next(0xFFFF); const bool qr = false; //要求 const bool aa = false; //権威なし var rd = (bool) Conf.Get("useRD"); //再帰要求を使用するかどうか const bool ra = false; //再帰無効 //リクエストパケットの生成 var sp = new PacketDns(id, qr, aa, rd, ra); AppendRr(sp, RrKind.QD, new RrQuery(requestName, dnsType)); //QR(質問)フィールド追加 const int port = 53; //SockUdp sockUdp = new UdpObj(Kernel, getLogger(), ip, port); byte[] sendBuf = sp.GetBytes(); var sockUdp = new SockUdp(_kernel, ip, port, null, sendBuf); //送信 //この辺のロジックを動作確認する必要がある byte[] recvBuf = sockUdp.Recv(timeout); if (recvBuf != null && 12 <= recvBuf.Length) { //受信 try { var rp = new PacketDns(recvBuf); var str = string.Format("{0} count[{1},{2},{3},{4}] rcode={5} AA={6}", requestName, rp.GetCount(RrKind.QD), rp.GetCount(RrKind.AN), rp.GetCount(RrKind.NS), rp.GetCount(RrKind.AR), rp.GetRcode(), rp.GetAa()); Logger.Set(LogKind.Detail, sockUdp, 18, str); //"Lookup" //質問フィールの以外のリソースデータをキャッシュする //for (int rr = 1; rr < 4; rr++) { foreach (RrKind rr in Enum.GetValues(typeof (RrKind))) { if (rr == RrKind.QD) { continue; //質問フィールの以外のリソースデータをキャッシュする } var m = rp.GetCount(rr); for (var n = 0; n < m; n++) { var oneRr = rp.GetRr(rr, n); _rootCache.Add(oneRr); Logger.Set(LogKind.Detail, sockUdp, 24, string.Format("{0} _rootCache.Count={1}", oneRr, _rootCache.Count)); //_rootCache.Add } } return rp; } catch (IOException) { //ここでのエラーログも必要? return null; } } Logger.Set(LogKind.Error, sockUdp, 5, string.Format("addr={0} requestName={1} dnsType={2}", remoteAddr, requestName, dnsType)); //Lookup() パケット受信でタイムアウトが発生しました。 return null; }
//アップロード(ファイル受信) bool UpLoad(SockUdp childObj,string path) { var ret = false; ushort no = 0; var totalSize = 0; FileStream fs = null; BinaryWriter bw = null; if (!(bool)Conf.Get("write")) {//「書込み」が許可されていない Logger.Set(LogKind.Secure,childObj,11,path); //エラーコード(2) アクセス違反 childObj.Send(Bytes.Create(Util.htons((ushort)Opcode.Error),Util.htons(2),"Transmission of a message prohibition")); goto end; } if (!(bool)Conf.Get("override")) {//「上書き」が許可されていない if (File.Exists(path)) { Logger.Set(LogKind.Secure,childObj,12,path); //エラーコード(6) アクセス違反 childObj.Send(Bytes.Create(Util.htons((ushort)Opcode.Error),Util.htons(6),"There is already a file")); goto end; } } //ACK(0)送信 childObj.Send(Bytes.Create(Util.htons((ushort)Opcode.Ack),Util.htons(no))); try { fs = new FileStream(path,FileMode.OpenOrCreate,FileAccess.Write); } catch (Exception e) { //エラーコード(2) アクセス違反 childObj.Send(Bytes.Create(Util.htons((ushort)Opcode.Error),Util.htons(2),e.Message)); goto end; } bw = new BinaryWriter(fs); while (true) { //受信 // if (!childObj.Recv(Timeout)) { var buf = childObj.Recv(Timeout); if (buf.Length==0) { Logger.Set(LogKind.Error,childObj,7,string.Format("{0}sec",Timeout)); break; } if ((Opcode)(buf[1]) != Opcode.Data) { break; } //次のデータかどうかの確認 if (Util.htons(BitConverter.ToUInt16(buf,2)) != no + 1) continue; no++; int size = buf.Length - 4; bw.Write(buf,4,size); //Write totalSize += size; //ACK送信 childObj.Send(Bytes.Create(Util.htons((ushort)Opcode.Ack),Util.htons(no))); if (size != 512) { Logger.Set(LogKind.Normal,childObj,8,string.Format("{0} {1}byte",path,totalSize)); ret = true; goto end; } Thread.Sleep(1); } end: if(bw!=null) bw.Close(); if(fs!=null) fs.Close(); return ret; }
//ダウンロード(ファイル送信) bool DownLoad(SockUdp childObj,string path) { var ret = false; var no = (ushort)1; var total = 0; FileStream fs = null; BinaryReader br = null; if (!(bool)Conf.Get("read")) {//「読込み」が許可されていない Logger.Set(LogKind.Secure,childObj,10,path); //エラーコード(2) アクセス違反 childObj.Send(Bytes.Create(Util.htons((ushort)Opcode.Error),Util.htons(2),"Receive of a message prohibition")); goto end; } if (!File.Exists(path)) {//ファイルが見つからない Logger.Set(LogKind.Secure,childObj,13,path); //エラーコード(1) ファイルが見つからない childObj.Send(Bytes.Create(Util.htons((ushort)Opcode.Error),Util.htons(1),"A file is not found")); goto end; } try { fs = new FileStream(path,FileMode.OpenOrCreate,FileAccess.Read); } catch (Exception e) { //エラーコード(2) アクセス違反 childObj.Send(Bytes.Create(Util.htons((ushort)Opcode.Error),Util.htons(2),e.Message)); goto end; } br = new BinaryReader(fs); while (true) { var data = br.ReadBytes(512); //DATA 送信 childObj.Send(Bytes.Create(Util.htons((ushort)Opcode.Data),Util.htons(no),data)); total += data.Length; if (data.Length < 512) { if (data.Length == 0) { //最後の 0bytes データを送る childObj.Send(Bytes.Create(Util.htons((ushort)Opcode.Data),Util.htons(no))); } Logger.Set(LogKind.Normal,childObj,9,string.Format("{0} {1}byte",path,total)); ret = true; goto end; } Thread.Sleep(10); // ACK待ち //if (!childObj.Recv(Timeout)) { var buf = childObj.Recv(Timeout); if (buf.Length==0) { Logger.Set(LogKind.Error,childObj,7,string.Format("{0}sec",Timeout)); break; } if ((Opcode)(buf[1]) != Opcode.Ack) break; //ACK番号が整合しているかどうかの確認 var ackNo = Util.htons(BitConverter.ToUInt16(buf,2)); if (no != ackNo) { Logger.Set(LogKind.Error,childObj,14,string.Format("no={0} ack={1}",no,ackNo)); //エラーとして処理する childObj.Send(Bytes.Create(Util.htons((ushort)Opcode.Error),Util.htons(2),"unmatch ACK")); goto end; } no++;//次のデータ } end: if (br != null) br.Close(); if (fs != null) fs.Close(); return ret; }