PDA

View Full Version : Cần lấy IP/name của máy đang kết nối



rass_it
18-04-2006, 11:49
Mình đang làm ct chat bằng Socket...
Khi máy client kết nối đến Sever/Client khác (mình làm được phần này rồi)nhưng bây giờ cần :
- máy Client A connect tới máy Clients B (hay Sever)
- máy B mở Socket để lắng nghe..
- Khi máy B chấp nhận kết nối tứ A đến thì mình muốn từ B sẽ tự động trả về cho A các T.tin như sau :
+ Địa chỉ (hay name..máy A) của máy đang connect tới B
+ Địa chỉ (hay name) của B...mục đích của mình là khi có máy nào connect với nhau thì các máy phải biết t.tin của nhau (IP,tên,port kết nối,..)để khi lần sau có gửi data(text,..) hay thứ gì khác thì mình chỉ cần truyền các t.tin (IP,tên,port,..) đã có trước đó (có thể t.tin đó dc lưu vào csdl hay ...)

Mình có đoạn code của client và sever như sau :

Sever ....


Imports IP
Imports System
Imports System.Net
Imports System.Net.Sockets
Imports System.Text
Imports System.Threading
Imports System.Text.RegularExpressions
Imports Microsoft.VisualBasic
Imports ASPSimply

Public Delegate Sub StatusInvoker(ByVal t As String)

Public Class Form1
Inherits System.Windows.Forms.Form

Private mobjThread As Thread
Private mobjListener As TcpListener
Private mcolClients As New Hashtable()

#Region " Windows Form Designer generated code "

Public Sub New()
MyBase.New()

'This call is required by the Windows Form Designer.
InitializeComponent()

'Add any initialization after the InitializeComponent() call

End Sub

'Form overrides dispose to clean up the component list.
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing Then
If Not (components Is Nothing) Then
components.Dispose()
End If
End If
MyBase.Dispose(disposing)
End Sub
Friend WithEvents lstStatus As System.Windows.Forms.ListBox

'Required by the Windows Form Designer
Private components As System.ComponentModel.Container

'NOTE: The following procedure is required by the Windows Form Designer
'It can be modified using the Windows Form Designer.
'Do not modify it using the code editor.
<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
Me.lstStatus = New System.Windows.Forms.ListBox()
Me.SuspendLayout()
'
'lstStatus
'
Me.lstStatus.Dock = System.Windows.Forms.DockStyle.Fill
Me.lstStatus.Name = "lstStatus"
Me.lstStatus.Size = New System.Drawing.Size(292, 264)
Me.lstStatus.TabIndex = 0
'
'Form1
'
Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
Me.ClientSize = New System.Drawing.Size(292, 273)
Me.Controls.AddRange(New System.Windows.Forms.Control() {Me.lstStatus})
Me.Name = "Form1"
Me.Text = "Socket Server"
Me.ResumeLayout(False)

End Sub

#End Region

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
mobjThread = New Thread(AddressOf DoListen)
mobjThread.Start()
UpdateStatus("Listener started")


End Sub

Private Sub DoListen()
Try
mobjListener = New TcpListener(5000)

mobjListener.Start()
Do
'Dim x As New Client(mobjListener.AcceptSocket)
Dim x As New Client(mobjListener.AcceptTcpClient)

AddHandler x.Connected, AddressOf OnConnected
AddHandler x.Disconnected, AddressOf OnDisconnected
'AddHandler x.CharsReceived, AddressOf OnCharsReceived
AddHandler x.LineReceived, AddressOf OnLineReceived
mcolClients.Add(x.ID, x)
Dim params() As Object = {"New connection"}
Me.Invoke(New StatusInvoker(AddressOf Me.UpdateStatus), params)
Loop Until False
Catch
End Try
End Sub

Private Sub OnConnected(ByVal sender As Client)
UpdateStatus("Connected")
'''Dim ty As System.Type = mobjListener.GetType()
'''MsgBox(ty)
'''Dim ssender As String
'''ssender = sender.ID()
'''MsgBox("" & ssender)
End Sub

Private Sub OnDisconnected(ByVal sender As Client)
UpdateStatus("Disconnected")
mcolClients.Remove(sender.ID)
End Sub

'Private Sub OnCharsReceived(ByVal sender As Client, ByVal Data As String)
' UpdateStatus("Chars:" & Data)
'End Sub

Private Sub OnLineReceived(ByVal sender As Client, ByVal Data As String)
Dim a As String
a = Network.IPAddresses("tuoc")

UpdateStatus(a & " " & Data) '"Line:"

Dim objClient As Client
Dim d As DictionaryEntry

For Each d In mcolClients
objClient = d.Value
objClient.Send(Data & vbCrLf)
Next
End Sub

Private Sub UpdateStatus(ByVal t As String)
lstStatus.Items.Add(t)
lstStatus.SetSelected(lstStatus.Items.Count - 1, True)
End Sub

Private Sub Form1_Closing(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles MyBase.Closing


'ASPSimply.Net.SocketTCPClient.OnLineReceivedEvent Handler = True

mobjListener.Stop()
End Sub


End Class



Client...



Imports IP
Imports System
Imports System.Net
Imports System.Net.Sockets
Imports System.Text
Imports System.Text.RegularExpressions
Imports Microsoft.VisualBasic
Imports ASPSimply


Public Class Form1
Inherits System.Windows.Forms.Form

Public Delegate Sub DisplayInvoker(ByVal t As String)

#Region " Windows Form Designer generated code "

Public Sub New()
MyBase.New()

'This call is required by the Windows Form Designer.
InitializeComponent()

'Add any initialization after the InitializeComponent() call

End Sub

'Form overrides dispose to clean up the component list.
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing Then
If Not (components Is Nothing) Then
components.Dispose()
End If
End If
MyBase.Dispose(disposing)
End Sub
Friend WithEvents txtDisplay As System.Windows.Forms.TextBox
Friend WithEvents txtSend As System.Windows.Forms.TextBox
Friend WithEvents btnSend As System.Windows.Forms.Button

'Required by the Windows Form Designer
Private components As System.ComponentModel.Container

'NOTE: The following procedure is required by the Windows Form Designer
'It can be modified using the Windows Form Designer.
'Do not modify it using the code editor.
<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
Me.btnSend = New System.Windows.Forms.Button()
Me.txtSend = New System.Windows.Forms.TextBox()
Me.txtDisplay = New System.Windows.Forms.TextBox()
Me.SuspendLayout()
'
'btnSend
'
Me.btnSend.Anchor = (System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Right)
Me.btnSend.Location = New System.Drawing.Point(360, 216)
Me.btnSend.Name = "btnSend"
Me.btnSend.Size = New System.Drawing.Size(56, 24)
Me.btnSend.TabIndex = 2
Me.btnSend.Text = "Send"
'
'txtSend
'
Me.txtSend.Anchor = ((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Left) _
Or System.Windows.Forms.AnchorStyles.Right)
Me.txtSend.Location = New System.Drawing.Point(8, 216)
Me.txtSend.Name = "txtSend"
Me.txtSend.Size = New System.Drawing.Size(344, 20)
Me.txtSend.TabIndex = 1
Me.txtSend.Text = ""
'
'txtDisplay
'
Me.txtDisplay.Anchor = (((System.Windows.Forms.AnchorStyles.Top Or System.Windows.Forms.AnchorStyles.Bottom) _
Or System.Windows.Forms.AnchorStyles.Left) _
Or System.Windows.Forms.AnchorStyles.Right)
Me.txtDisplay.Multiline = True
Me.txtDisplay.Name = "txtDisplay"
Me.txtDisplay.ReadOnly = True
Me.txtDisplay.Size = New System.Drawing.Size(424, 208)
Me.txtDisplay.TabIndex = 0
Me.txtDisplay.TabStop = False
Me.txtDisplay.Text = ""
'
'Form1
'
Me.AcceptButton = Me.btnSend
Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
Me.ClientSize = New System.Drawing.Size(424, 245)
Me.Controls.AddRange(New System.Windows.Forms.Control() {Me.btnSend, Me.txtSend, Me.txtDisplay})
Me.Name = "Form1"
Me.Text = "Socket Client"
Me.ResumeLayout(False)

End Sub

#End Region

Private mobjClient As TcpClient
Private marData(1024) As Byte
Private mobjText As New StringBuilder()

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'mobjClient = New TcpClient("localhost", 5000)
mobjClient = New TcpClient("tuoc", 5000) 'hitachi
'If ASPSimply.Net.SocketTCPClient.OnConnectedEventHand ler () true Then
Dim tt As String
tt = ""
If tt = "" Then
Dim a1 As System.Net.Sockets.LingerOption
a1 = Me.mobjClient.LingerState
MsgBox(a1.LingerTime)

End If
DisplayText("Connected to host" & vbCrLf)

mobjClient.GetStream.BeginRead(marData, 0, 1024, AddressOf DoRead, Nothing)

'Send("New client online")
Dim a As String
a = Network.IPAddresses("tuoc")
MsgBox("a= " & a)
Send(a & " " & "Online")
End Sub

Private Sub btnSend_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSend.Click
Dim a, t As String
a = Network.IPAddresses("tuoc")
t = a & " " & txtSend.Text
Send(t) '(txtSend.Text)
txtSend.Text = ""
End Sub

Private Sub Send(ByVal t As String)
Dim w As New IO.StreamWriter(mobjClient.GetStream)
w.Write(t & vbCr)
w.Flush()
End Sub

Private Sub DoRead(ByVal ar As IAsyncResult)
Dim intCount As Integer

Try
intCount = mobjClient.GetStream.EndRead(ar)
If intCount < 1 Then
MarkAsDisconnected()
Exit Sub
End If

BuildString(marData, 0, intCount)

mobjClient.GetStream.BeginRead(marData, 0, 1024, AddressOf DoRead, Nothing)
Catch e As Exception
MarkAsDisconnected()
End Try
End Sub

Private Sub BuildString(ByVal Bytes() As Byte, ByVal offset As Integer, ByVal count As Integer)
Dim intIndex As Integer

For intIndex = offset To offset + count - 1
If Bytes(intIndex) = 10 Then
mobjText.Append(vbLf)

Dim params() As Object = {mobjText.ToString}
Me.Invoke(New DisplayInvoker(AddressOf Me.DisplayText), params)

mobjText = New StringBuilder
Else
mobjText.Append(ChrW(Bytes(intIndex)))
End If
Next
End Sub

Private Sub MarkAsDisconnected()
txtSend.ReadOnly = True
btnSend.Enabled = False
End Sub

Private Sub DisplayText(ByVal t As String)
txtDisplay.AppendText(t)
End Sub

Private Shared Function IPAddresses(ByVal server As String) As String

Try
Dim ASCII As New System.Text.ASCIIEncoding

' Get server related information.
Dim heserver As IPHostEntry = Dns.Resolve(server)

' Loop on the AddressList
Dim curAdd As IPAddress
Dim ip As String
For Each curAdd In heserver.AddressList

' Display the type of address family supported by the server. If the
' server is IPv6-enabled this value is: InternNetworkV6. If the server
' is also IPv4-enabled there will be an additional value of InterNetwork.

'MsgBox("Addressfamily:" & curAdd.AddressFamily.ToString)
'Console.WriteLine(("AddressFamily: " + curAdd.AddressFamily.ToString()))

' Display the ScopeId property in case of IPV6 addresses.
If curAdd.AddressFamily.ToString() = ProtocolFamily.InterNetworkV6.ToString() Then
'Console.WriteLine(("Scope Id: " + curAdd.ScopeId.ToString()))
'MsgBox("Scope id :" & curAdd.ScopeId.ToString)
End If

' Display the server IP address in the standard format. In
' IPv4 the format will be dotted-quad notation, in IPv6 it will be
' in in colon-hexadecimal notation.

'MsgBox("Address :" & curAdd.ToString)
Dim a As String
a = curAdd.ToString
'MsgBox("" & a)
Return a

'Console.WriteLine(("Address: " + curAdd.ToString()))

' Display the server IP address in byte format.

'MsgBox("AddressBytes :")
'Console.Write("AddressBytes: ")



Dim bytes As [Byte]() = curAdd.GetAddressBytes()
Dim i As Integer
For i = 0 To bytes.Length - 1
'MsgBox("" & bytes(i))
'Console.Write(bytes(i))
Next i
'MsgBox("" & ControlChars.Cr & ControlChars.Lf)
'Console.WriteLine(ControlChars.Cr + ControlChars.Lf)
Next curAdd

Catch e As Exception
Console.WriteLine(("[DoResolve] Exception: " + e.ToString()))
End Try

End Function 'IPAddresses
End Class


hàm IPAdrress(name as string) trong client thì mình gọi từ thư viện 'IP'
tham số truyền vào là 'tên máy'..và nó sẽ trả ra d/c tương ứng của máy này....

Mong các bạn góp ý cho ct của mình và giúp mình hoàn thành yêu cầu như trên..thanks a lot my buddies.. :) :)

nguoivodanh1003
18-04-2006, 12:32
Đọc thêm link sau: http://msdn2.microsoft.com/en-us/library/system.net.sockets.socket(VS.80).aspx

rass_it
18-04-2006, 14:42
To nguoivodanh1003 :bạn có vd nào đơn giản hơn ? cái này nó nói về kết nối đến một HTTP sever thôi...mình cần là cho 1 windows application (viết bằng VB.NET)

Bạn nào có thì share cho mình đi ...đang cần gấp lắm (Phải nộp cho sếp...sếp đang grr.. )

nguoivodanh1003
20-04-2006, 03:29
Rass_it, bạn có thể post đủ source để chạy test không. Tui thử copy code để thử thì báo thiếu Imports ASPSimply and IP, bạn có thể bỏ lên để làm thử hay không.

rass_it
20-04-2006, 10:26
Mình có gửi file zip của CT này qua d/c của bạn ...bạn xem thử coi...Rất cám ơn về góp ý và sự giúp đỡ của bạn..

rass_it
22-04-2006, 09:11
Có bạn nào biết làm vấn đề này xin góp ý và giúp mình với,,,tới giờ vẫn chưa tiến triển gì nhiều...mình cũng đọc về kỹ thuật lập trình bằng Socket nhưng quá rời rạc nên...với lại mới làm quen với việc đọc ebooks nên còn hạn chế trong việc có thể hiểu ngay những gì đã đọc ngay được....

cám ơn các bạn trước nha..

nguoivodanh1003
24-04-2006, 23:22
Rass, xin lổi chưa trả lời cho ông được, tui phải bỏ không đi 1 cái đám cưới, 1 chầu cafe, 2 chầu nhậu để ngồi làm giúp ông, đang co tiến triển tốt, nhưng còn đang bị bug, Sever bị kick out. Để thư thả vài hôm tui gởi cho ông. Phải đi làm ăn nên kô có nhiều thời gian.

rass_it
25-04-2006, 09:37
Hì hì ..:)
không sao..Có thực mới vực được đạo mà !?
Cậu thường Online không để có gì mình dễ trao đổi với nhau hơn...
Thanks a lót for your help and idea

nguoivodanh1003
26-04-2006, 13:10
rass, tui đã làm xong chương trình chat rồi, sẽ gởi mail cho ông. Chương trình cũng còn nhiều hạn chế nhưng dùng để chat được, vã lại cũng co nhiều cái hay bạn co thể dùng vào chương trình của bạn.
Bạn nào cần thì tui sẽ send cho, nhưng các bạn có modify cái gì hay thì gởi lại để tui học hỏi thêm, ngoài ra các bạn có dùng chuơng trình của tui thì làm ơn để tên tui trên đó nha.

rass_it
26-04-2006, 17:21
Chạy thì tương đối ổn nhưng khi nhấn nút minimize của Client thì bên Sever nó hiểu là Client... Log Out nhưng vẫn gửi dl được...

TH 2:
Trên một máy chạy 1 Sever và chạy n(mình chạy thử là 3) Client thì khi Client thứ nhất (C1) log in thì trên Sẻver hiện ra ở status display là 127.0.0.1 Log in
- sau đó chạy thêm Client(C2) nữa thì trên Sever hiện tiếp các dòng sau :
127.0.0.1 Log out
127.0.0.1 Log in
Theo mình : thì Server đã hiểu là C1 đã out và C2 Log in ....nhưng trong lúc này thì cả 2 đều có thể gửi dl qua Server bình thường...
- T.tương như vậy khi chạy thêm 1 Client nữa (C3)..
- khi có nhiều Client cùng chạy một lúc thì mình nhấn chuột vào C1 / C2 / C3.....thì Server cũng hiểu là Client đó 'Log Out'...

Mình mới nhận chiều nay nên chưa hiểu hết code bạn đã sửa thêm....bạn viết nó rên nền VS 2003 hay 2005....mình thử chạy trên 2003 thì nó như vậy đấy...

Bạn coi lại thử coi nhé.....mình về nhà coi code đó đây.có gì mình hỏi bạn sau vậy...Thanks ....Have a funny day !!!?

nguoivodanh1003
26-04-2006, 21:30
Tui viết bằng 2005, nếu chạy bằng 2003 thì create new Project rồi copy mấy cái form qua compile bình thường.
Bạn mô tả nhự vậy là đúng rồi:
- o Sever có checking chỉ cho phép 1 máy co 1 IP connect vào sever thôi, nếu có cái thứ 2 connect vào thí server sẻ kick out cái client mới đó, infor Out là của thằng thứ n connect (n > 1), muốn cho phép thì vào bên server comment cai đoạn này:
If blnExist Then
' If that IP is still in
' Inform and kick him out
OutboundPacket = "FIN|"
Else

To Hell: Tui đã gởi cho ông rồi đó. Tui viết cái này bang VB2005 vì theo yêu cầu của Rass thi phải dùng VB, như trên đã nói neu dùng VB03 thi tạo project mới rồi copy mấy cái form về là được.

rass_it
27-04-2006, 12:35
mình add TCPServer từ 2005 qua 2003 thì chạy được...
nhưng làm như vậy với TCPClient thì không được ..nó bào nhiều lỗi quá không bít gì luôn....

nllytgnp
27-04-2006, 13:15
thôi cái đó dễ mà thứ gì
có gì hỏi hvitual@gmail.com

rass_it
27-04-2006, 17:22
Có địa chỉ yahoo ? mình Add mãi vào yahoo để chat mà không được...

nguoivodanh1003
27-04-2006, 23:05
tui đã convert to VB2003 phần client rồi đó, đã send mail cho ông rồi, nhưng cái VB03 tui chưa có test.
Chúc vui vẽ.

ngvhung2k1
05-05-2006, 16:03
nguoivodanh1003 ơi, bạn có thể gởi chương trình source của chương trình chat đó được kô?
mail: ngvhung@gmail.com hay ngvhung2k1@yahoo.com
cám ơn bạn nhiều.