📄 np_tcp_window.py
字号:
################################################################################ ## Copyright 2005 University of Cambridge Computer Laboratory. ## ## This file is part of Nprobe. ## ## Nprobe is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation; either version 2 of the License, or ## (at your option) any later version. ## ## Nprobe is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with Nprobe; if not, write to the Free Software ## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ## ################################################################################from Tkinter import *#from np_obnode import *from minmax import MIN, MAX, MAX3, BIGNUMBERfrom nprobe import SERVER, CLIENT, http_client_method_stringfrom np_packet_markers import *from np_lookups import np_hostnamefrom np_widgets import Can, NOSCROLLfrom np_drawutil import inside, Nodraw, endpointsfrom np_seq import SEQ_MAX, seq_add, seq_sub, seq_diff, seq_gt, seq_gte, \ seq_lt, seq_ltefrom np_longutil import tsDatestringfrom np_TCP import trig_strfrom math import modffrom np_bitmaps import ccross, med_dash############################################################################################################################################################## TCP_WDW_HT = 900## TCP_WDW_WI = 750## TCP_WDW_HT = 1100## TCP_WDW_WI = 950TCP_WDW_HT = 768TCP_WDW_WI = 1024TCP_HMARGIN_PROP = 8# % of whole window#TCP_CANVAS_HT_PROP = 70TCP_CANVAS_HT_PROP = 80TCP_FLIGHT_HT_PROP = 10TCP_RTT_HT_PROP = 10# % of sectionTCP_CANV_VMARGIN_PROP = 5TCP_FLIGHT_VMARGIN_PROP = 10TCP_RTT_VMARGIN_PROP = 10MIN_XTIC_PROP = 12MIN_YTIC_PROP = 7RTT_ZOOM_FACT = 2RTT_SCROLL_FACT = 1.1############################################################################################################################################################## BG_COL = 'black'## FG_COL1 = 'white'## FG_COL2 = 'green'## FG_COL3 = 'red'## FG_COL4 = 'blue'## FG_COL5 = 'OrangeRed1'## FG_COL6 = 'chocolate4'## FG_COL7 = 'chartreuse4'BG_COL = 'white'FG_COL1 = 'black'FG_COL2 = 'green'FG_COL3 = 'red'FG_COL4 = 'blue4'FG_COL5 = 'OrangeRed1'FG_COL6 = 'chocolate4'FG_COL7 = 'chartreuse4'AXES_COL = FG_COL1ATTENTION_COL = FG_COL3LOW_ATTENTION_COL = FG_COL6S_SEG_COL = 'DodgerBlue3'S_ACK_COL = 'dodger blue'S_WDW_COL_SS = 'MediumPurple'S_WDW_COL_CA = 'red'S_WDW_COL_SC = 'SteelBlue2'C_SEG_COL = 'chartreuse3'C_ACK_COL = 'PaleGreen1'C_WDW_COL_SS = '#aaca00'C_WDW_COL_CA = 'red'C_WDW_COL_SC = 'green'TOT_RTT_COL = FG_COL4## BG_COL = 'white'## FG_COL1 = 'black'INFO_FONT = ("7x13")TIC_FONT = ("7x13")PKT_LABEL_FONT = ("6x9")############################################################################################################################################################## Canvas on which it is all drawn#class TCP_canv: def __init__(self, master, conn, pktlist, indx1, indx2, w, h, xpos, ypos, bgcol=BG_COL, fgcol=FG_COL1): global S_SEG_COL self.Display = master.Display self.pktlist = pktlist self.modelled = conn.modelled self.indx1 = indx1 self.indx2 = indx2 self.fgcol = fgcol self.bgcol = bgcol self.wi = wi = int(w) self.ht = ht = int(h) #S_SEG_COL = fgcol## # all proportionate self.hmargin = (wi*TCP_HMARGIN_PROP)/100 self.xorg = self.hmargin self.xwi = wi-(2*self.hmargin) self.xrmargin = self.xorg+self.xwi self.canv = canv = Can(master, wi, ht, 0, 0, NOSCROLL) canv.config(bg=bgcol, cursor=(ccross, 'orange')) canv.place(x=xpos, y=ypos, width=wi, height=ht) canv.fgcol = fgcol canv.bgcol = bgcol canv.scaleline = None canv.scaletxt = None canv.Canv = self self.rboxing = 0 canv.rbox = None #self.make_rbuttons() self.pkt_info_canv = None self.conn = conn self.pktlist = pktlist self.indx1 = indx1 self.indx2 = indx2 self.wdw = master self.xpos = xpos self.ypos = ypos self.rttinfo = [] self.phandles = [] self.rtthandles = [] self.move_rel = 0 Widget.bind(self.canv, "<1>", self.mouse_1_down) Widget.bind(self.canv, "<B1-Motion>", self.mouse_1_drag) Widget.bind(self.canv, "<ButtonRelease-1>", self.mouse_1_up) #Widget.bind(self.canv, "<Double-Button-1>", self.mouse_1_dblclick) Widget.bind(self.canv, "<2>", self.mouse_2_down) Widget.bind(self.canv, "<B2-Motion>", self.mouse_2_drag) Widget.bind(self.canv, "<Shift-B2-Motion>", self.mouse_2_shift_drag) Widget.bind(self.canv, "<Control-B2-Motion>", self.mouse_2_control_drag) Widget.bind(self.canv, "<ButtonRelease-2>", self.mouse_2_up) Widget.bind(self.canv, "<3>", self.mouse_3_down) Widget.bind(self.canv, "<B3-Motion>", self.mouse_3_drag) Widget.bind(self.canv, "<ButtonRelease-3>", self.mouse_3_up) Widget.bind(self.canv, "<Double-Button-3>", self.wdw.mouse_3_dblclick) Widget.bind(self.canv, "<4>", self.mouse_4) Widget.bind(self.canv, "<5>", self.mouse_5) self.draw() ############################################################################## def rtt_scaleup(self, fact): self.canv.delete('rtt') self.canv.delete('rtt_tic') self.srscalef = self.srscalef*fact self.crscalef = self.crscalef*fact self.draw_rtts()############################################################################## def rtt_scaledown(self, fact): self.canv.delete('rtt') self.canv.delete('rtt_tic') self.srscalef = self.srscalef/fact self.crscalef = self.crscalef/fact self.draw_rtts()############################################################################## def mouse_1_down(self, event): # set origin of selection box canv = event.widget x = canv.canvasx(event.x) y = canv.canvasy(event.y) #print 'B1 %d, %d' % (x, y) #if y < self.yorg+self.canv_vmargin: if inside(x, y, self.mouse_bounds): self.rboxing = 1 canv.startx = canv.lastx = x canv.starty = canv.lasty = y canv.rbox = None elif inside(x, y, self.rtt_bounds): self.rtt_scaleup(RTT_ZOOM_FACT)############################################################################## def mouse_1_drag(self, event): # draw selection box canv = event.widget x = canv.canvasx(event.x) y = canv.canvasy(event.y) #if y < self.yorg+self.canv_vmargin: if inside(x, y, self.mouse_bounds): if self.rboxing and canv.startx != x and canv.starty != y : canv.delete(canv.rbox) self.rboxing = 1 canv.rbox = canv.create_rectangle( canv.startx, canv.starty, x, y, outline=self.fgcol) canv.lastx = x canv.lasty = y else: # just entered self.rboxing = 1 canv.startx=x canv.starty=y canv.rbox = None ############################################################################## def mouse_1_up(self, event): def sort_pkt_by_time(a, b): if a.tm > b.tm: return 1 elif a.tm < b.tm: return -1 else: return 0 def pktlists_same(a, b): # return 1 if same if len(a) != len(b): return 0 else: for i in range(len(a)): if a != b: return 0 return 1 canv = event.widget if canv.rbox != None: canv.delete(canv.rbox) canv.rbox = None x = canv.canvasx(event.x) y = canv.canvasy(event.y) #if y < self.yorg+self.canv_vmargin and self.rboxing: #if 1: #if inside(x, y, self.mouse_bounds): if self.rboxing: self.rboxing = 0 items = list(canv.find_overlapping(canv.startx, canv.starty, canv.lastx, canv.lasty)) pktlist = [] pktdict = {} # accumulate like this to avoid duplications for h in self.phandles: if items.count(h[1]): pktdict[h[0]] = 1 pktlist = pktdict.keys() if len(pktlist) > 1: pktlist.sort(sort_pkt_by_time) indx1 = pktlist[0].indx indx2 = pktlist[-1].indx if indx1 != self.indx1 or indx2 != self.indx2: #draw the new zoomed canvas self.wdw.canvasses.append(TCP_canv(self.wdw, self.conn, self.pktlist, indx1, indx2, self.wi, self.ht, 0, 0)) self.wdw.canvas_curr = self.wdw.canvas_curr + 1############################################################################## def mouse_2_down_canv(self, event): def make_pkt_info_canv(master): c = Canvas(master, width=500, height=500) c.config(bg=master.bgcol) return c canv = event.widget x = canv.canvasx(event.x) y = canv.canvasy(event.y) found_seg = 0 self.move_rel = 0 item = canv.find_closest(x, y)[0] #print 'item is ' #print item #print self.phandles for h in self.phandles: if item == h[1]: #print 'found item ' #print item found_seg = 1 c = self.pkt_info_canv = make_pkt_info_canv(canv) bb = self.Display.canv.pkt_txt(h[0], 0, extend = 'true', fold='true', scol=S_SEG_COL, canv=c) width = bb[2]-bb[0] xpos = MIN(x+5, TCP_WDW_WI - width) c.place(x=xpos, y=y+5, anchor=NW, width=width, height=bb[3]-bb[1]) break if not found_seg: for tag in ['crel', 'srel', 'cack', 'sack']: tags = list(canv.find_withtag(tag)) #print tags l = tags #print l if tags.count(item): #print 'XXX GOT C' self.move_rel = tags self.relstartpos = (x, y) self.relpos = (x, y) self.move_tag = tag c = self.pkt_info_canv = make_pkt_info_canv(canv) break############################################################################## def mouse_2_drag(self, event): self.mouse_2_drag_common(event, 0)############################################################################## def mouse_2_shift_drag(self, event): self.mouse_2_drag_common(event, 1)############################################################################## def mouse_2_control_drag(self, event): self.mouse_2_drag_common(event, 2)############################################################################## def mouse_2_drag_common(self, event, constraint): if self.move_rel: canv = event.widget #print 'Moving' x = canv.canvasx(event.x) y = canv.canvasy(event.y) if y < self.yorg: #print 'at %d %d relpos %d %d' % (x,y, self.relpos[0],self.relpos[1] ) xdiff = (x-self.relpos[0]) ydiff = (y-self.relpos[1]) #print 'diff %d %d' % (xdiff, ydiff) self.relpos = (x, y) if constraint == 1: xdiff = 0 if constraint == 2: ydiff = 0 self.slide(canv, x, y, xdiff, ydiff)############################################################################## def mouse_2_up_canv(self, event): c = self.pkt_info_canv if c != None: c.destroy() self.pkt_info_canv = None if self.move_rel: canv = event.widget #print 'Moving' x = canv.canvasx(event.x) y = canv.canvasy(event.y) xdiff = (x-self.relstartpos[0]) ydiff = (y-self.relstartpos[1]) #print 'diff %d %d' % (xdiff, ydiff) self.slide(canv, x, y, -xdiff, -ydiff) canv.delete('tmp')############################################################################## def slide(self, canv, x, y, xd, yd): for t in self.move_rel: xy = canv.coords(t) if len(xy) == 2: #text x1 = xy[0]+xd y1 = xy[1]+yd canv.coords(t, x1, y1) else: #line x1 = xy[0]+xd y1 = xy[1]+yd x2 = xy[2]+xd y2 = xy[3]+yd canv.coords(t, x1, y1, x2, y2) #canv = self.pkt_info_canv td = (x-self.relstartpos[0])/self.tscalef sd = int((y-self.relstartpos[1])/self.sscalef) tstr = '%+.3f %+d' % (td/1000, -sd) canv.delete('tmp') if x + 125 > self.wi: anch = E else: anch = W canv.create_text(x+5, y-5, fill=self.fgcol, font=("helvetica", 8), anchor=anch, text=tstr, tag='tmp')############################################################################## def mouse_3_down(self, event): # rb scaler canv = event.widget x = canv.canvasx(event.x) y = canv.canvasy(event.y) canv.scalestartx = x canv.scalestarty = y canv.scaleline = None canv.scaletxt = None if inside(x, y, self.rtt_bounds): #scale for server or client? r = 2 got = 0 while not got: items = canv.find_overlapping(x-r, y-r, x+r, y+r) for i in items: l = list(canv.gettags(i)) if l.count('rtt'): got = 1 break r = r+2 if l.count('c'): self.rttscaling = self.crscalef self.rttscalingcol=C_SEG_COL elif l.count('s'): self.rttscaling = self.srscalef self.rttscalingcol=S_SEG_COL else: print 'unknown rtt tag' sys.exit(1)############################################################################## def mouse_3_drag(self, event): def txt1(tmd, sd, ib): return '%+.3f %+d\n IB=%.3fMbs' % (tmd/1000.0, sd, ib) def txt2(tmd, sd, ib): return '%+.3f %+d' % (tmd/1000.0, sd) def txt3(tmd, sd, ib): return '%+.3f %+.3f' % (tmd/1000.0, sd/1000.0) # show scaled values canv = event.widget x = canv.canvasx(event.x) y = canv.canvasy(event.y) col = self.fgcol # beware noisy mouse buttons try: if x != canv.scalestartx or y != canv.scalestarty: canv.delete(canv.scaleline) canv.delete(canv.scaletxt) canv.scaleline = canv.create_line(canv.scalestartx, canv.scalestarty, x, y, fill=FG_COL5) if y < self.yorg+self.canv_vmargin/2: yscalef = self.sscalef textf = txt1 elif y < self.flight_yorg+self.flight_vmargin/2: yscalef = self.fscalef textf = txt2 else: yscalef = self.rttscaling if not yscalef: return col = self.rttscalingcol textf = txt3 tmd = (x-canv.scalestartx)/self.tscalef atmd = abs(tmd) sd = (canv.scalestarty-y)/yscalef asd = abs(sd) if atmd: ib = (asd*8.0)/atmd else: ib = 0.0 if x + 100 > self.wi: anch = E else: anch = W
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -