เล่าสู่กันฟัง ... โค้ดโปรแกรมนี้ เป็นส่วนหนึ่งของการเขียนขึ้นมาเพื่อตรวจสอบสถานะการออนไลน์ ของไอ้โรคจิตตัวหนึ่ง ที่พยายามจะ Spam เว็บไซต์ของผม และผมก็เฝ้ารอเก็บข้อมูลไว้ทั้งใน Web DataBase ทั้งส่งออกไปเก็บไว้ใน GMail และ Logging File ของตัว Server เองเอาไว้เพียบเลย สุดท้ายก็ตามมันเจออยู่ที่บริษัทฯ ขายระบบ Network แห่งหนึ่งในกรุงเทพฯ แถวสาธร (เพราะมันพลาดเอง ที่ใช้ Fix IP 203.130.134.xxx บริษัทฯของมันมา) แต่ครั้นพอผมปรึกษากะทนาย คุยกะตำรวจ เรื่อง พ.ร.บ. คอมฯ ปี 50 ตามมาตรา 10 ว่าผมต้องใช้หลักฐานอะไรบ้าง ... แป่ว !!! ... ไม่มีใครรู้เรื่องเลย เพราะข้อมูลที่มีมันเป็นสื่ออิเล็กทรอนิกส์ทั้งหมด อีกทั้งยังเป็นเรื่องที่ใหม่ด้วย ก็เลยเอาว่ะ ล็อคระบบทุกอย่างไว้หมด แล้วก็อโหสิให้มันไปก็แล้วกัน ... เพราะจริงๆแล้ว สิ่งที่มันทำไป ก็แทบไม่มีผลอะไรต่อ Server อยู่แล้วล่ะครับ (นี่แหละปัญหาทางกฏหมาย คือ เจตนามันน่ะใช่ แต่ผลเสียหายมันไม่เกิดขึ้น เฮ้อ) ... ถือซ่ะว่าทำบุญทำทานปล่อยตัวเงินตัวทองเข้าป่าไป ...
|
 |
ผมจะไม่กล่าวถึงทฤษฎีของระบบเครือข่ายน่ะครับ อันนี้ไปหาข้อมูลเพิ่มเติมเอาเองคงไม่ยาก สำหรับยุคสมัยนี้ ... โค้ดโปรแกรมตัวนี้แท้ที่จริงก็ทำงานคล้ายๆกับการใช้คำสั่ง PING ใน DOS Command นั่นแหละครับ ... สำหรับ Visual Basic 6 เราจะนำเอา Winsock Control (MSWINSCK.OCX) เข้ามาใช้งาน
โดยมีลักษณะการทำงาน ดังนี้คือ
- กำหนดหมายเลข IP Address และ หมายเลข Port ให้กับเจ้า Winsock นี่ซ่ะ
- จากนั้นสั่งให้ Connect ไปยังเครื่องปลายทางตามที่เรากำหนดค่าเอาไว้
- หาก Winsock สามารถติดต่อกับเครื่องปลายทางได้ มันจะกระโดดไปทำงานยังเหตุการณ์ (หรือ โปรแกรมย่อย) ที่ชื่อว่า Winsock_Connect() เราก็สามารถเอาข้อมูล IP Address นี้ให้แสดงผลเป็นการ On ได้ ในทางกลับกันหากเชื่อมต่อกันไม่ได้ มันก็ไม่ไปยังเหตุการณ์ Connect
- จากนั้นเราก็สั่งให้วน Loop เพื่อรับค่า IP Address ตัวใหม่เข้ามาจนกว่าจะครบ ... จบ (เรื่องง่ายจริงๆเลย)
- ขอให้สังเกตว่า การวน Loop นั้น ต้องใช้การทำงานของ Timer เข้ามาช่วยน่ะครับ จะใช้พวก For, Do, While ลักษณะนี้ไม่ได้ เพราะมันเกี่ยวข้องกับเรื่องของเวลาด้วย
โค้ดตัวนี้สามารถทดสอบการเชื่อมต่อ (Connect) ได้ทั้งเครือข่าย LAN (Local Area Network) ภายใน และ ยังสามารถตรวจสอบออกไปยังระบบเครือข่ายอินเทอร์เน็ตได้ด้วยน่ะครับ ขอบอกครับขอบอก ... แต่ทั้งนี้หากนำเอา บทความโปรแกรมอ่านค่า MAC Address ในเครือข่าย LAN มาใช้งานด้วย ก็ตามชื่อครับ จะอ่านค่า MAC Address ได้เฉพาะวง LAN เท่านั้นน่ะครับพี่น้อง ... กรณีหากจะอ่านค่า MAC Address ในวง LAN เข้ามาด้วย ก็เชิญโมดิฟายกันเอาเองได้ตามสะดวกน่ะครับ เอิ๊กๆๆๆ
 ขอยืม IP Address ของ มหาวิทยาลัยเทคโนโลยีพระจอมเกล้า พระนครเหนือ มาใช้เป็นตัวอย่างครับ (ผมศิษย์เก่าครับ ... เอา IP ที่อื่นมาแสดงเดี๋ยวเขาจะว่าเอา) ส่วนชื่อเครื่อง หรือ DNS (Domain Name Server) ที่เห็นนั่นคือ การแปลงจากค่า IP Address มาครับ (เพื่อให้ง่ายกว่าการจดจำหมายเลข IP Address นั่นเอง) ซึ่งในบทความชุดนี้ยังไม่มี อันนี้เอาไว้รอบหน้าก็แล้วกันน่ะครับ ... ทำให้อยากแล้วจากไป 55555+
|
 |
 ใช้ Component เพิ่มมาอีก 2 ตัว โดยเลือกจากเมนู Project --> Components ...
 Design Time
รังน้อยๆของทองก้อน (หรือบางวันก็กลายสภาพเป็น นารีแขยงคาเฟ่ เอิ๊กๆๆๆๆ)
- IP: 192.168.1.1 - Router
- IP: 192.168.1.11 - Windows Server 2003/MS SQL Server และเป็น Backup Data
- IP: 192.168.1.20 - เครื่องอีนังหมูสับของผมเอง (ก็ทั้งสับ ทั้งยัดไส้มันซ่ะจนจะเละแล้ว) เป็นเครื่องหลักที่ใช้งาน
- IP: 192.168.1.100 - ต่อเข้ากับ Dream Box (DM600 PVR) แบบดูทีวีฟรีๆ อิอิอิอิอิ ... เพราะถูกหยามหยันว่าผมมี TV จอ LCD Bravia ของ Sony ซ่ะดิบดี แต่ดันใช้เสาอากาศแบบหนวดกุ้ง มันไม่ได้สมราคากันเลย ... 55555+
- IP: 192.168.1.21 - (ภาพข้างล่าง) เป็นเครื่องใช้ทดสอบโปรแกรมต่างๆที่ผมเขียนขึ้นมา 1 อาทิตย์จะลง Windows XP ใหม่ตลอด
- IP: 192.168.1.22 - (ภาพข้างล่าง) NoteBook ตัวนี้ลง Win 7 เพื่อทดสอบโปรแกรมอีกเช่นกัน
 Run Time
มาดูโค้ดกันเถอะ ...
Option Explicit
' นับจำนวน IP Address ที่ตรวจพบ
Dim CountIP As Long
' เก็บค่า IP ชุดสุดท้ายของค่าเริ่มต้นเอาไว้ เช่น 192.168.0.1 จะเก็บค่า 1
Dim IPStartScan As Integer
' เก็บค่า IP ชุดสุดท้ายของค่าสิ้นสุดเอาไว้ เช่น 192.168.0.254 จะเก็บค่า 254
Dim IPEndScan As Integer
' เก็บค่า IP 3 ชุดแรก เช่น 192.168.0.254 จะเก็บค่า 192.168.0 เอาไว้
Dim strIP As String
' ตัวแปรเก็บค่าสถานะของการ Scan หา IP
' หากเป็นจริง สถานะกำลัง Scan
' หากเป็นเท็จ สถานะหยุดการ Scan
Dim blnScan As Boolean
' กรณีสั่งหยุดการ Scan
Private Sub cmdStop_Click()
' กำหนด False เพื่อหยุดการ Scan IP Address
blnScan = False
End Sub
Private Sub Form_Load()
' ตั้งฟอร์มอยู่กึ่งกลาง
Me.Move (Screen.Width - Me.Width) \ 2, (Screen.Height - Me.Height) \ 2
' ปิด Timer เอาไว้ก่อน เพราะยังไม่ได้สั่งให้มันทำงาน
Timer1.Enabled = False
' ตัวอย่างน่ะครับ
txtStartIP(0).Text = "192"
txtStartIP(1).Text = "168"
txtStartIP(2).Text = "0"
txtStartIP(3).Text = "0"
txtEndIP(0).Text = "192"
txtEndIP(1).Text = "168"
txtEndIP(2).Text = "0"
txtEndIP(3).Text = "255"
txtPort.Text = "80"
txtScanResult.Text = ""
cmdStop.Enabled = False
End Sub
' ###################################################
' การกดปุ่มให้เริ่มต้น Scan หา IP Address
' ###################################################
Private Sub cmdScan_Click()
On Error GoTo ErrorHandler
Dim Count As Integer
' ตรวจสอบว่า IP เริ่มต้นในการค้นหา ทั้ง 4 ชุด เป็นค่าว่างหรือไม่
For Count = 0 To 3
If Trim(txtStartIP(Count).Text) = "" Or Len(Trim(txtStartIP(Count).Text)) = 0 Then
MsgBox "กรุณาป้อนหมายเลข IP Address ให้ถูกต้องด้วย.", vbOKOnly + vbExclamation, "รายงานสถานะ"
Exit Sub
End If
Next Count
' ตรวจสอบว่าป้อนหมายเลข Port หรือไม่
If Trim(txtPort.Text) = "" Or Len(Trim$(txtPort.Text)) = 0 Then
MsgBox "กรุณาป้อนหมายเลข Port ก่อนด้วย.", vbOKOnly + vbExclamation, "รายงานสถานะ"
Exit Sub
End If
' เคลียร์ข้อมูล Status Bar ใน Panel แรก
sbMain.Panels(1).Text = ""
' เคลียร์ค่า TextBox ในการแสดงผลหมายเลข IP Address
txtScanResult.Text = ""
' เคลียร์ค่าการนับจำนวน IP
CountIP = 0
' กำหนดช่วงเวลาในการ Scan หา IP Address
' บางครั้งก็อาจจะต้องกำหนดให้ใช้เวลานาน เพราะมันขึ้นกับสายและระยะทาง หรืออื่นๆ ด้วยน่ะครับ
Timer1.Interval = 100
' หาก IP ชุดสุดท้ายไม่เป็นค่าว่าง
If Trim(txtEndIP(3).Text) <> "" Or Len(Trim(txtEndIP(3).Text)) = 0 Then
cmdScan.Enabled = False
cmdStop.Enabled = True
' แจ้งหมายเลข Port
txtScanResult.Text = txtScanResult.Text & "ตรวจสอบหมายเลข Port: " & txtPort.Text & vbCrLf
' กำหนดค่าหมายเลข IP ในการเริ่มต้น Scan หา เอาเฉพาะ 3 ชุดแรก เช่น 192.168.0
' แล้วค่อยๆทำการนับหมายเลขชุดสุดท้ายขึ้นไปทีละ 1
strIP = txtStartIP(0).Text & "." & txtStartIP(1).Text & "." & txtStartIP(2).Text
' กำหนดหมายเลข IP Address เริ่มต้น (ชุดสุดท้าย)
IPStartScan = txtStartIP(3).Text
' กำหนดหมายเลข IP ที่สิ้นสุด (ชุดสุดท้าย)
IPEndScan = txtEndIP(3).Text
' ขณะนี้กำลังทำการ Scan เมื่อไรก็ตามที่ค่านี้มีค่าเป็น False ก็จะหยุดการทำงานลงทันที
blnScan = True
' กระตุ้นนาฬิกาให้ทำงานต่อไป
Timer1.Enabled = True
End If
ExitProc:
Exit Sub
ErrorHandler:
' ขณะโปรแกรมกำลังทำงาน (Run Time) ดัก Error จาก On Error GoTo ErrorHandler
If Err.Number <> 0 Then MsgBox "Error " & Err.Number & vbCrLf & Err.Description
Resume ExitProc
End Sub
' ###################################################
' โปรแกรมย่อยในการ Scan หา IP Address ตามช่วงที่กำหนดเอาไว้
' ###################################################
Private Sub ScanIP()
On Error GoTo ErrorHandler
' เงื่อนไขให้ Scan เมื่อ IP ชุดสุดท้ายของค่าเริ่มต้น ยังน้อยกว่าหรือเท่ากับ IP ชุดสุดท้ายของค่าสิ้นสุด
' และ ยังไม่มีการกดปุ่ม cmdStop ให้หยุดการทำงาน
If IPStartScan <= IPEndScan And blnScan = True Then
' ให้ CPU ไปทำงานอย่างอื่นได้เลย (คืน CPU กลับไปให้กับระบบปฏิบัติการ - OS)
DoEvents
' หาก Winsock ยังมีการ Connect กับ IP ใดๆอยู่ ต้องสั่งให้ Disconnect ออกไปก่อน
If wsIP.State <> sckClosed Then wsIP.Close
' ###################################################
' ส่วนสำคัญที่กำหนดค่าเพื่อทำการทดสอบ
' กำหนด IP ให้กับ Winsock เมื่อ
' strIP เก็บค่า IP 3 ชุดแรก เช่น 192.168.0.111 ก็จะเก็บค่า 192.168.0 เอาไว้
' IPStartScan เก็บค่า IP ชุดสุดท้าย หรือ IP ที่กำลังตรวจสอบการ Connect กับ Winsock
wsIP.RemoteHost = strIP & "." & IPStartScan
' กำหนดหมายเลข Port ในการติดต่อกับ Remote IP
wsIP.RemotePort = txtPort.Text
' Winsock ติดต่อหมายเลข IP Address และ หมายเลข Port ตามที่กำหนด
' หวกสามารถติดต่อ IP Address และ Port ที่กำหนดได้ ก็จะกระโดดไปเหตุการณ์ wsIP_Connect()
' หากว่ามันติดต่อกับเครื่องปลายทางไม่ได้ มันก็จะไม่กระโดดไปในเหตุการณ์ Connect น่ะครับ
' จากนั้นเราก็ให้มันแสดงผลตามหมายเลข IP Address ออกมายังไงล่ะครับ
' จะเห็นการทำงานในส่วนนี้ได้ คุณต้องทำการ Debug ดูด้วยน่ะครับ ...
wsIP.Connect
' ###################################################
' เพิ่มค่า IP ในการ Scan ขึ้นอีก 1
IPStartScan = IPStartScan + 1
' Scan หา IP Address ครบแล้ว หรือ สั่งให้หยุดการ Scan
Else
cmdScan.Enabled = True
cmdStop.Enabled = False
' สั่งให้ Timer1 หยุดการทำงานด้วย
Timer1.Enabled = False
' รายงานผลการ Scan IP Address ใน StatusBar
If IPStartScan <= IPEndScan Then
sbMain.Panels(1).Text = "หยุดการทำงานที่ IP: " & IPStartScan
' กรณี Scan IP Address เสร็จสมบูรณ์หมดแล้ว
Else
sbMain.Panels(1).Text = "การทำงานเสร็จสมบูรณ์ - " & CountIP & " IP Address"
MsgBox "Scan หา IP ในระบบได้ " & CountIP & " หมายเลข - Port " & txtPort.Text
End If
End If
ExitProc:
Exit Sub
ErrorHandler:
' ขณะโปรแกรมกำลังทำงาน (Run Time) ดัก Error จาก On Error GoTo ErrorHandler
If Err.Number <> 0 Then MsgBox "Error " & Err.Number & vbCrLf & Err.Description
Resume ExitProc
End Sub
' ###################################################
' ตราบใดที่ Timer1.Enabled = True มันก็จะเข้ามาทำงานที่นี่ ตามค่า Interval ที่ตั้งเอาไว้
' ###################################################
Private Sub Timer1_Timer()
' หาก Timer1 มีค่า Enabled ก็จะสั่งให้ไปทำงานที่โปรแกรมย่อย ScanIP ตามเวลาที่กำหนด
sbMain.Panels(1).Text = "กำลังประมวลผล IP: " & strIP & "." & IPStartScan
' ไป Scan หา IP Address หรือ
' ตรวจสอบการ Connect IP Address กับ Winsock Control นั่นแหละครับ
Call ScanIP
End Sub
' ###################################################
' โปรแกรมย่อยในการตรวจสอบการ Connect กับ Winsock หรือไม่
' หากมีการ Connect กับ IP ที่ทดสอบอยู่ให้ทำการแจ้งผลใน TextBox
Private Sub wsIP_Connect()
' ###################################################
On Error GoTo ErrorHandler
' แสดงผลหมายเลข IP Address ใน TextBox
txtScanResult.Text = txtScanResult.Text & "IP : " & wsIP.RemoteHost & vbCrLf
' นับจำนวน IP Address ที่ตรวจพบ
CountIP = CountIP + 1
ExitProc:
Exit Sub
ErrorHandler:
' ขณะโปรแกรมกำลังทำงาน (Run Time) ดัก Error จาก On Error GoTo ErrorHandler
If Err.Number <> 0 Then MsgBox "Error " & Err.Number & vbCrLf & Err.Description
Resume ExitProc
End Sub
Private Sub cmdExit_Click()
Set frmIPScan = Nothing
End
End Sub
|
Conclusion: จากโปรแกรมนี้ เป็นการวนรอบตามหมายเลข IP Address โดยทดสอบได้เพียงครั้งละ 1 Port เท่านั้น ... กรณีที่เราอยากตรวจสอบ Port ต่างๆ ของแต่ละ IP Address ใดๆ 1 IP แทน ทั้งเครื่องเราเอง หรือ เครื่องอื่นๆ ว่ามีการเปิด Port ไหนเอาไว้บ้าง ก็เพียงแต่กำหนด หรือ Fix IP Address ไว้เพียง 1 หมายเลขเท่านั้น จากนั้นก็สั่งให้วนรอบตามหมายเลข Port แทน ... ลองนำไปปรับแต่งเพิ่มเติมกันเอาเองเลยครับ ... ไม่ยากหรอกครับพี่น้อง ...
|