Solved

For Idle_Mind : Colelction problem

Posted on 2003-11-18
29
316 Views
Last Modified: 2010-05-03
please explain your collection problem in here . thanks
0
Comment
Question by:ANGmoh
  • 12
  • 12
  • 5
29 Comments
 
LVL 1

Author Comment

by:ANGmoh
Comment Utility
if i want to save it into text files , so how shall it be ?
the text content should be "Ip1,Ip2,Ip3 ..." or shall i make it

ip1
ip2
ip3
...
...

and when form load , it'll load the content into a listbox ?
and when there's an incoming connection , check if the ip match any ips that are in the listbox ?

for i = 0 to list1.listcount
  if IP = list1.list(i) then
   true
  else
   false
next i ?
0
 
LVL 85

Expert Comment

by:Mike Tomlinson
Comment Utility
No Problem!  Would love to help.

I have to take my daughter to kindergarten and the dog to the vet though so I should be back between one and two hours.

Idle_Mind
0
 
LVL 85

Expert Comment

by:Mike Tomlinson
Comment Utility
This is simple app to show how to use a collection with strings.

Create a new project and add a textbox and three command buttons.

When the program loads it looks for App.Path & "\Banned IP's.txt" and loads the data if it exists.  When the program exits, the data is written back to the file.

Type an IP into the text box and hit "Add IP".
You can check whether or not an IP has been banned by hitting the "Is Banned?" button.
The "Remove IP" will remove whatever IP is in the textbox from your banned list.

Be sure to close the app with the "X" so that the data will be written back to the file.  Hitting the stop button doesn't fire the Form_Unload event.

Add/Remove some IP's and check for their existence.  Then go out and look at the resulting text file.  It's fast and simple.

Checking for the existence of a key in a collecion is extremely fast.  Internally, the VB Collection stores the address of every item in the linked list by computing a hash value from the assigned key.  For large data sets, determining the address of an item from a key will almost always be faster then a search algorithm in an array.

Regards,

Idle_Mind

' ******************* Code Follows **********************
Option Explicit

Dim banned As Collection

Private Sub Form_Load()
    Dim ip As String
   
    Command1.Caption = "Add IP"
    Command2.Caption = "Remove IP"
    Command3.Caption = "Is Banned?"
   
    Set banned = New Collection
    If Dir(App.Path & "\Banned IP's.txt") <> "" Then
        Open App.Path & "\Banned IP's.txt" For Input As #1
        Do While Not EOF(1)
            Line Input #1, ip
            banned.Add ip, ip
        Loop
        Close #1
    End If
End Sub

Private Sub Command1_Click()
    addIP Trim(Text1.Text)
End Sub

Private Sub Command2_Click()
    removeIP Trim(Text1.Text)
End Sub

Private Sub Command3_Click()
    If isBannedIP(Trim(Text1.Text)) Then
        MsgBox Text1.Text & " IS on the banned list"
    Else
        MsgBox Text1.Text & " IS NOT on the banned list"
    End If
End Sub

Private Sub addIP(ip As String)
     ' adding duplicate key will cause error
     ' in our cause this means the IP has already been banned
    On Error Resume Next
    banned.Add ip, ip
End Sub

Private Sub removeIP(ip As String)
    On Error Resume Next ' removing key that doesn't exist causes error
    banned.Remove ip
End Sub

Private Function isBannedIP(ip As String) As Boolean
    On Error GoTo noSuchKey
   
    Dim bannedIp As Variant
   
    banned.Remove ip ' if it was removed successfully
    banned.Add ip, ip ' put it back
    isBannedIP = True ' they are on the banned list
    Exit Function
   
noSuchKey:
    isBannedIP = False ' got here because they weren't in the collection
End Function

Private Sub Form_Unload(Cancel As Integer)
    Dim ip As Variant
   
    Open App.Path & "\Banned IP's.txt" For Output As #1
    For Each ip In banned
        Print #1, ip
    Next ip
    Close #1
End Sub
0
 
LVL 7

Assisted Solution

by:Enlade
Enlade earned 30 total points
Comment Utility

Just to give Idle_Mind a head start let me ask you one question that might help him to manage the IP's when you start to add and remove them programmatically.

How do you get the IP's into your data file?  Will your program be adding and removing them?  If so, then I am thinking that you might want to use a fixed sized/record based random access file rather than a variable line length text file.  Its just that you seem to be focusing on reading the file, storing it in memory, and then searching to see if an IP is in the list.  However, the only real thinking involved in this problem is in removing IPs from the list.  It is easy enough to remove an IP from the list in memory, but you need to think of a good way to remove it from the file.  Not that it will be all that hard to come up with a strategy to remove the IP's.  That’s not what I'm saying.  I'm just saying that if you order the complexity of each step involved with your overall problem you will find that the removal of IPs from the file will be near the top of your list.

So, maybe if you restrict the adding and removing of IP’s to the program (not allowing people to edit the IP’s from a text editor) then that might give Idle_Mind some other possibilities.  Mind you, I think it would be nice to be able to view or edit the IPs directly from a text editor as well as from the program.  So, you probably would like to keep the file as a text file even if you had to rewrite the full file every time the user removed an IP (though there are better ways).

Anyway, here are the functions you need to write.

LoadBannedIPList
CheckIPSyntax
IsBannedIP
RemoveBannedIP
AddBannedIP

And depending on how you organize you data you might also need.

SortBannedIPList
SaveBannedIPList

I think that is about all you will need to consider.
0
 
LVL 7

Expert Comment

by:Enlade
Comment Utility

Opps, apparently you can run your errands faster then I can type....hee hee.

Yep, you have chosen to rewrite the full banned IP file.  So long as the program does not crash or the computer is not turned off accidentally then the list should remain intact.
0
 
LVL 7

Expert Comment

by:Enlade
Comment Utility

The only thing I would recommend is that you add a CheckIPSyntax function before you add the IP to your collection (which you do in two places).
0
 
LVL 85

Expert Comment

by:Mike Tomlinson
Comment Utility
All very good points Enlade.

I agree that there could be better management of the data file and validation of the IP's.  I don't think ANGmoh has ever used a collection before so I wanted to keep the app real simple so it would be easy to see what is going on.

One way to keep the file and collection synchronized without a lot of work, would be to simply rewrite the data file anytime an IP as added/removed.  Unless many IP's are added/removed in fast succession (which I don't think they will be in this case), speed shouldn't be a problem.

Again, this was just a simple program to demonstrate the feasability of using a collection.  It would most certainly be bullet-proofed if it were going into one of my apps.

Regards,

Idle_Mind
0
 
LVL 85

Expert Comment

by:Mike Tomlinson
Comment Utility
ANGmoh,

I wouldn't bother loading the banned IP's into a listbox on your main form.  In my opinion, that would be a waste of memory and precious real estate on your screen.  

I would create a different form just for managing the banned IP's.  It would be very easy to modify the code I gave you to also load the IP's into a listbox and then add buttons to add/remove from the list just like I did.

Idle_Mind
0
 
LVL 1

Author Comment

by:ANGmoh
Comment Utility
Idle_Mind , so u mean that if the admin doesnt wish to add/edit the ip banned list , so i'd only load the ips into buffer and check them ? and if they admin wish to view the ban list , then load the buffer into the listbox ?

from what i'v read from the code , to me , "banned"  is  just something like a buffer to store those ips , am i correct ?

0
 
LVL 1

Author Comment

by:ANGmoh
Comment Utility
Another extra question worth 50 points too :)

so i'm doing a chat server , is there any way to obtain important and relevant information about the server ?

what information can be important for a web admin should know ?

i'v added user counters , total incoming connection request /rejected connection / current users connected, server uptime , server ip/port/hostname .. i feel that something i'm missing too .. can u guys please help me to think more about what info i can add ?
0
 
LVL 85

Expert Comment

by:Mike Tomlinson
Comment Utility
I guess you could think of the banned Collection as a buffer.  There is a lot more going on under the hood than meets the eye though. =)

Here are the differences between an array and a collection.

An array is a contiguous block of memory.  Each item in the array takes up the same amount of space so when you want to get to index 5, you multiply the size of one item by 5, and jump that distance linearly from the begginning of the array to get to that location.  When you remove an item from an array, you must shift all the items behind it down to fill the "hole" that was left behind.  Similarly when you want to increase the size of the array, a second, larger contiguous block of memory must be created and then all the existing data copied over.

In a collection, each item is stored at a different place in memory.  The first item has a pointer that tells it where to go in memory to find the next item.  In this way, the items in a collection are joined together like the cars of a train.  This is commonly known as linked list structure.  This structure makes it easy to add an item since you only have update the last item to point to the new item.  Likewise, when an item is removed, you simply tell the item before it to point to whatever is pointed to after what was being removed.  The rest of the items don't have to be touched.  The other feature of a collection is the ability to assign a key, or unique id to each item added to it.  The collection uses a hash function to break that key down into a number, and then stores the address of the node (the cars on our train) there.  The hashing function is written such that the location of the address of the node can be determined in just several iterations.  

If and/or when you want to edit the banned list visually, just load the items in the collection to a list box:

Dim ip as variant
List1.Clear ' If it's not already empty, make it so
For Each ip in banned
    List1.Add ip
Next ip

Regards,

Idle_Mind
0
 
LVL 1

Author Comment

by:ANGmoh
Comment Utility
Idle_Mind : i guess i am understand :)

what about my second question ?
0
 
LVL 85

Expert Comment

by:Mike Tomlinson
Comment Utility
Sounds like you've got a pretty start on server stats.  I can' think of anything else to collect right now.  I'll let you know if I think of anything though.

Idle_Mind
0
 
LVL 1

Author Comment

by:ANGmoh
Comment Utility
no problem .

anyway , Enlade , thanks for your opinion , u'll be awarded too :)

but i'll only close this question if i got the second part completed :) if not probably i'll substitute it with another question .
0
Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

 
LVL 1

Author Comment

by:ANGmoh
Comment Utility
Idle_Mind or anyone , well i'v found a question to substitute my second question ..and this question worth 50 points .

so let's say now i have a Listbox which will display Server's Name , txtbox1 display IP , txtbox2 display Port .

users may add / edit or delete any server. and the corresponded IP and port will be deleted too.
i wish to store them in a plain text file , so how can i retrieve it and display them ? i dun wish to use db , bcos they are just for clients .

example :

in serverInfo.txt file , it'll have
"server1" , "120.0.0.1" , "1234"
"server2" , "123.253.165.12" , "552"
"server3" , 123.222.125.2" , "2222"
....
...
when form load , it'll load ONLY the server's name into a listbox , and the txtIP.text and txtPort.text will only shows the ip and port which is correspond to the server.

so when users add it , it'll create a new row , which will store server name , ip and port
when delete it , it'll remove.

can i know how to do it ?  using listview ?

thanks
0
 
LVL 7

Expert Comment

by:Enlade
Comment Utility

I will let Idle_Mind help you on this one.  But I will suggest that you just do it the same way that Idle_Mind has already told you except that instead of reading the line into a variable called ip you read it into some other variable (call it stLine or something).  Then you can use the split command to split the line based on the "," seperator.  So, create a function (call it ParseLine) that will take stLine and return the serverName, IP, and Port.  That ParseLine function simply uses the Split command to get each of those data items.

Also, do not put the quotes around each item in the data file.  Just put commas between each and leave out the quotes.  They will just make things harder and since they are not needed they are just more typing or wasted disk space.

In any case, you can then put the data items into collections as Idle_Mind suggested.  Or you could put them into an array of some record type.  Like this:

Public Type BannedIPInfoType
  ServerName as string
  IP as string
  Port as string
End Type

Public BannedIPs() as BannedIPInfoType
Public nBannedIPs as long

Then you could sort the array if you want to speed up the processing searching though with only a few IPs sorting might not be needed.

Or, you could use collections.  It works either way.  Idle_Mind has already given you most of what you need to do so I'll let him finish it up.
0
 
LVL 7

Expert Comment

by:Enlade
Comment Utility

By the way, I tend to lean more towards creating my own data types and using arrays, but thats just because I come from a C/C++ background.  In VB memory management is slow and messy so collections can be useful to overcome some deficits in the way VB manages memory.  So, even though I lean towards creating an array I won't defend that position.  Its just the way I like to see my code is all.  I don't like collections, but thats just me being silly.
0
 
LVL 85

Expert Comment

by:Mike Tomlinson
Comment Utility
Here is the previous project with the servers added in.  In all, it needs a textbox, listbox, three labels and four commandbuttons.

In addition to the banned IP code, It shows how to read/write the Servers.txt file, and how to parse the selected line in the server listbox.

Regards,

Idle_Mind

' ************************* Code Follows *************************
Option Explicit

Dim banned As Collection

Private Sub Form_Load()
    Dim ip As String
   
    Command1.Caption = "Add IP"
    Command2.Caption = "Remove IP"
    Command3.Caption = "Is Banned?"
    Command4.Caption = "Save Servers"
   
    Set banned = New Collection
    If Dir(App.Path & "\Banned IP's.txt") <> "" Then
        Open App.Path & "\Banned IP's.txt" For Input As #1
        Do While Not EOF(1)
            Line Input #1, ip
            banned.Add ip, ip
        Loop
        Close #1
    End If
   
    Dim inputLine As String
    If Dir(App.Path & "\Servers.txt") <> "" Then
        Open App.Path & "\Servers.txt" For Input As #1
        Do While Not EOF(1)
            Line Input #1, inputLine
            List1.AddItem inputLine
        Loop
        Close #1
    End If
End Sub

Private Sub Command1_Click()
    addIP Trim(Text1.Text)
End Sub

Private Sub Command2_Click()
    removeIP Trim(Text1.Text)
End Sub

Private Sub Command3_Click()
    If isBannedIP(Trim(Text1.Text)) Then
        MsgBox Text1.Text & " IS on the banned list"
    Else
        MsgBox Text1.Text & " IS NOT on the banned list"
    End If
End Sub

Private Sub Command4_Click()
    Dim a As Integer
   
    Open App.Path & "\Servers.txt" For Output As #1
    For a = 0 To List1.ListCount - 1
        Print #1, List1.List(a)
    Next a
    Close #1
End Sub

Private Sub addIP(ip As String)
     ' adding duplicate key will cause error
     ' in our cause this means the IP has already been banned
    On Error Resume Next
    banned.Add ip, ip
End Sub

Private Sub removeIP(ip As String)
    On Error Resume Next ' removing key that doesn't exist causes error
    banned.Remove ip
End Sub

Private Function isBannedIP(ip As String) As Boolean
    On Error GoTo noSuchKey
   
    Dim bannedIp As Variant
   
    banned.Remove ip ' if it was removed successfully
    banned.Add ip, ip ' put it back
    isBannedIP = True ' they are on the banned list
    Exit Function
   
noSuchKey:
    isBannedIP = False ' got here because they weren't in the collection
End Function

Private Sub List1_Click()
    Dim inputString As String
    Dim values As Variant
    If List1.ListIndex <> -1 Then
        inputString = List1.List(List1.ListIndex)
        values = Split(inputString, ",")
        Label1.Caption = Trim(values(0))
        Label2.Caption = Trim(values(1))
        Label3.Caption = Trim(values(2))
    End If
End Sub

Private Sub Form_Unload(Cancel As Integer)
    Dim ip As Variant
   
    Open App.Path & "\Banned IP's.txt" For Output As #1
    For Each ip In banned
        Print #1, ip
    Next ip
    Close #1
End Sub
0
 
LVL 1

Author Comment

by:ANGmoh
Comment Utility
ok thanks i'll try out the code first before i give points to both of you . i'll increase points to 130, where Idle_Mind gets 100 points , Enlade gets 30 points for ur comments .

i know the code will work , but i have to understand it before i accept any comments :)
0
 
LVL 1

Author Comment

by:ANGmoh
Comment Utility
Idle_Mind : well , i'm able to to save the data and load the list on startup. but i couldnt find a way to retrieve the data from the collection .

server.txt will store the data in
server1,Ip1,port1
server2,ip2,port2
server3,ip3,port3

so on form_load , i retrieve the content from the server.txt and save them into
 Serverinfo.add serverdata, serverdata
and using split() to load the server name only to the list box

now what i want to do is , when user select any server from the listbox , the text1.text and text2.text will become the corresponded server's ip and port

eg : List1.list(list1.listindex) = server1
then text1 = ip1 , text 2 = port2
so i guess we have to retrieve it from ServerInfo collection rite ? or ?

thanks

0
 
LVL 85

Accepted Solution

by:
Mike Tomlinson earned 100 total points
Comment Utility
No Problem.

This how you would load the data from server.txt:

    Dim inputLine As String
    Dim values As Variant
    Set serverInfo = New Collection
    If Dir(App.Path & "\Server.txt") <> "" Then
        Open App.Path & "\Server.txt" For Input As #1
        Do While Not EOF(1)
            Line Input #1, inputLine
            values = Split(inputLine, ",")
            List1.AddItem values(0)
            serverInfo.Add inputLine, values(0)
        Loop
        Close #1
    End If

This how you would retrieve the data from the collection when the listbox is clicked:

Private Sub List1_Click()
    Dim inputString As String
    Dim values As Variant
    If List1.ListIndex <> -1 Then
        inputString = serverInfo.Item(List1.List(List1.ListIndex))
        values = Split(inputString, ",")
        Text1.Text = Trim(values(1))
        Text2.Text = Trim(values(2))
    End If
End Sub

Regards,

Idle_Mind
0
 
LVL 85

Expert Comment

by:Mike Tomlinson
Comment Utility
To write the servers back to the file it then be:

    Dim server As String
   
    Open App.Path & "\Server.txt" For Output As #1
    For Each server In serverInfo
        Print #1, server
    Next server
    Close #1

Idle_Mind
0
 
LVL 1

Author Comment

by:ANGmoh
Comment Utility
oh ok thanks .

anyway , the first stage of my chat system is going to complete soon ,and i hope someone like you , Idle_Mind or Enlade , vb experts can evaluate my system , and tell me if there's any wrong with my coding (logic errors) , and i hope i can get some feedback .

*i'm still a newbie in vb , and i think some codings , even though they are running perfectly , but actually they are wrong !

so i hope anyone or both of you can guide me :P

Idle_Mind or Enlade , would you spare some time for it ?

i'll award 200 points for each of you,or maybe more . thanks .
0
 
LVL 85

Expert Comment

by:Mike Tomlinson
Comment Utility
Post your code and I would be more than happy to take a look.  I always like to see how other people do things.

Idle_Mind
0
 
LVL 1

Author Comment

by:ANGmoh
Comment Utility
Idle_Mind : because this is a project for my school work , so i dont wish to be publicly disclosed.  also , it invovles thousands lines of coding ( because of my bad coding practice) so i dont think it's a good idea to post in here .

or if you dont mind , can i have your email add and i'd send my system to you ?
0
 
LVL 85

Expert Comment

by:Mike Tomlinson
Comment Utility
You can email me at smckTomlinson@Adelphia.net.

But...you must close this and the other question and awards points on the topics discussed only here in EE.  The points don't necessarily have to be to me...they should be awarded to whomever you feel gets the points on the topics discussed in those threads.

According to EE Policy we are not allowed to communicate via email.  This means you cannot give me any additional points for any suggestion I give you based upon my viewing of your emailed code.  I don't have a problem with that and would still be willing to look at your project.  It just means others would not have the same opportunity and so no points should be awarded beyond this point.

Regards,

Idle_Mind
0
 
LVL 1

Author Comment

by:ANGmoh
Comment Utility
hmm ok then . ok then i'd close this Q first and i'll ask you questions in EE based on your suggestions given to me  , is that alrite ?
0
 
LVL 85

Expert Comment

by:Mike Tomlinson
Comment Utility
You must make that decisiobn.  If you continue to use the forum though, you will get suggestions from other people as well.

This is a good thing as my way is not the only way to do things...and I certainly won't claim they are the best!

=)

Idle_Mind

"A mind is like a parachute, it works best when open..."
0
 
LVL 1

Author Comment

by:ANGmoh
Comment Utility
dont worry , i know what to do :)
0

Featured Post

6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

Join & Write a Comment

Introduction In a recent article (http://www.experts-exchange.com/A_7811-A-Better-Concatenate-Function.html) for the Excel community, I showed an improved version of the Excel Concatenate() function.  While writing that article I realized that no o…
Enums (shorthand for ‘enumerations’) are not often used by programmers but they can be quite valuable when they are.  What are they? An Enum is just a type of variable like a string or an Integer, but in this case one that you create that contains…
Get people started with the process of using Access VBA to control Outlook using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Microsoft Outlook. Using automation, an Access applic…
Get people started with the process of using Access VBA to control Excel using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Excel. Using automation, an Access application can laun…

744 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now