|
|
#1 |
|
Addicted Member
Join Date: Dec 07
Posts: 166
![]() |
Im learning Tcp communication right now, and Im a newbie :P
First can i add a component to the form for tcpclient and tcpserver like a add one for a textbox and a botton? Second, which method is better Dim listener As Net.Sockets.TcpListener Dim listenThread As Threading.Thread or Dim tcpClient As New System.Net.Sockets.TcpClient() what should i use? |
|
|
|
|
|
#2 |
|
Member
Join Date: Nov 07
Posts: 47
![]() |
Re: [2008] Can I add a TCPClient Component
It matters what you are trying to accomplish with your program. Do you want the listener on a different thread?
"First can i add a component to the form for tcpclient and tcpserver like a add one for a textbox and a botton?" Do you mean drag and drop? |
|
|
|
|
|
#3 |
|
Addicted Member
Join Date: Dec 07
Posts: 166
![]() |
Re: [2008] Can I add a TCPClient Component
yes i mean drag and drop
and what i want to do is 2 simple programs that send strings to each others. |
|
|
|
|
|
#4 |
|
Networker
Join Date: Aug 05
Location: Sweden
Posts: 7,328
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() |
Re: [2008] Can I add a TCPClient Component
The TcpClient is not a control that can be dragged onto the form, its a class of which you create an instance at runtime and use however you want.
__________________
---My Flickr photo stream. Have a look! Rate posts that helped you. I do not reply to PM's with coding questions. How to Get Your Questions Answered LINQ examples | Save/load a forms layout | TCP client/server connection | Retrieving the EventHandler for any Event by code. Check out the work in progress: Obtuze - A Neural Network for OCR |
|
|
|
|
|
#5 |
|
Addicted Member
Join Date: Dec 07
Posts: 166
![]() |
Re: [2008] Can I add a TCPClient Component
ok, now can somone give me the simplest example possible :P
Please Client: How To connect Send Data Recieve Data Server: How To listen Send Data Receive Data Ive searched the form and google, but Im not understanding the code :S I need something very simple |
|
|
|
|
|
#6 |
|
Networker
Join Date: Aug 05
Location: Sweden
Posts: 7,328
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() |
Re: [2008] Can I add a TCPClient Component
There are so many examples all over this forum, it shouldnt be needed to create yet another one.
__________________
---My Flickr photo stream. Have a look! Rate posts that helped you. I do not reply to PM's with coding questions. How to Get Your Questions Answered LINQ examples | Save/load a forms layout | TCP client/server connection | Retrieving the EventHandler for any Event by code. Check out the work in progress: Obtuze - A Neural Network for OCR |
|
|
|
|
|
#7 |
|
.NUT
Join Date: May 05
Location: Sydney, Australia
Posts: 54,913
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() |
Re: [2008] Can I add a TCPClient Component
The MSDN Library documentation contains examples too. Have you read the documentation?
Note that a class must inherit, either directly or indirectly, the System.ComponentModel.Component class in order to be created in the designer. The System.Windows.Forms.Control class inherits Component, so all controls can be added in the designer. If you ever want to know whether a class can be created in the designer in future you don't need to ask. Simply open its MSDN documentation and check its ancestry for the Component class.
__________________
![]() 2007, 2008, 2009, 2010 Why is my data not saved to my database? | Communicating between multiple forms | MSDN Data Walkthroughs MSDN "How Do I?" Videos: VB | C# VBForums Database Development FAQ My CodeBank Submissions: VB | C# (ForumAccount has translated some of my VB submissions to C#) My Blog: Defining and Raising Custom Events | Manipulating GDI+ Drawings | Using Parameters in ADO.NET |
|
|
|
|
|
#8 |
|
Addicted Member
Join Date: Dec 07
Posts: 166
![]() |
Re: [2008] Can I add a TCPClient Component
so I will follow Atheist's example since it looks pretty simple
The client side would be then Code:
Dim listener As Net.Sockets.TcpListener Dim listenThread As Threading.Thread Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load listener = New Net.Sockets.TcpListener("127.0.0.1", 32111) listener.Start() listenThread = New Threading.Thread(AddressOf DoListen) listenThread.IsBackground = True listenThread.Start() End Sub
Code:
Dim listener As Net.Sockets.TcpListener Private Sub DoListen() 'This is the sub that does all the actual "listening". Its an endless loop that calls the AcceptTcpClient method over and over. 'If there is no connecting TcpClient, it will raise an exception but we will ignore this by catching it in a try statement and doing nothing with it. 'On the other hand, If a client has connected, it proceeds to the next line and a streamreader reads the incoming stream and shows it in a messagebox. Dim sr As IO.StreamReader Do Try Dim client As Net.Sockets.TcpClient = listener.AcceptTcpClient sr = New IO.StreamReader(client.GetStream) MessageBox.Show(sr.ReadToEnd) sr.Close() Catch End Try Loop End Sub this will only connect the two programs? how to send information after connection? |
|
|
|
|
|
#9 |
|
Frenzied Member
Join Date: Mar 06
Location: Pennsylvania
Posts: 1,069
![]() |
Re: [2008] Can I add a TCPClient Component
Did you look at msdn's 101 code examples? The Sockets example shows you how to do all of this, including sending messages back and forth, in a simplistic manner.
|
|
|
|
|
|
#10 |
|
Lively Member
Join Date: May 07
Posts: 87
![]() |
Re: [2008] Can I add a TCPClient Component
Try winsocket.
http://www.vwsoftwaresolutions.nl/winsock2005.dll.zip Its much easier to use when you dont know anything about networking(programming) and if you would understand you should write something like this on your own anyway. Gl with it |
|
|
|
|
|
#11 | |
|
Networker
Join Date: Aug 05
Location: Sweden
Posts: 7,328
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() |
Re: [2008] Can I add a TCPClient Component
Quote:
1. They provide much more functionallity and flexibility. 2. If you dont learn the basics of Tcp communications in .Net and begin using a component like this, as soon as you want to make the slightest change in how the Winsock component works, you're gonna get stuck.
__________________
---My Flickr photo stream. Have a look! Rate posts that helped you. I do not reply to PM's with coding questions. How to Get Your Questions Answered LINQ examples | Save/load a forms layout | TCP client/server connection | Retrieving the EventHandler for any Event by code. Check out the work in progress: Obtuze - A Neural Network for OCR |
|
|
|
|
|
|
#12 | |
|
Networker
Join Date: Aug 05
Location: Sweden
Posts: 7,328
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() |
Re: [2008] Can I add a TCPClient Component
Quote:
__________________
---My Flickr photo stream. Have a look! Rate posts that helped you. I do not reply to PM's with coding questions. How to Get Your Questions Answered LINQ examples | Save/load a forms layout | TCP client/server connection | Retrieving the EventHandler for any Event by code. Check out the work in progress: Obtuze - A Neural Network for OCR |
|
|
|
|
|
|
#13 |
|
Addicted Member
Join Date: Dec 07
Posts: 166
![]() |
Re: [2008] Can I add a TCPClient Component
i dont need it to be more effective. im still trying to make my client and server connect!!
so the code u provide is only for the server not the client... ? right? im not understanding the code... is it for 2 programs or is it only for the server? if its only for the server, could you PLEASE show me how a client would connect.. |
|
|
|
|
|
#14 | |
|
Networker
Join Date: Aug 05
Location: Sweden
Posts: 7,328
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() |
Re: [2008] Can I add a TCPClient Component
Quote:
Anyway, I'll create one more example.. Server side: Form: VB.Net Code:
VB.Net Code:
Client Side: Form: VB.Net Code:
I've tried to put some comments in the code but dont hesitate to look the different methods/classes up on MSDN. Edit: I intend to update this example some day soon.
__________________
---My Flickr photo stream. Have a look! Rate posts that helped you. I do not reply to PM's with coding questions. How to Get Your Questions Answered LINQ examples | Save/load a forms layout | TCP client/server connection | Retrieving the EventHandler for any Event by code. Check out the work in progress: Obtuze - A Neural Network for OCR Last edited by Atheist; Apr 11th, 2009 at 08:23 AM. |
|
|
|
|
|
|
#15 |
|
Addicted Member
Join Date: Dec 07
Posts: 166
![]() |
Re: [2008] Can I add a TCPClient Component
thanks a million
I will check this code and reply asap thanks again |
|
|
|
|
|
#16 |
|
Addicted Member
Join Date: Dec 07
Posts: 166
![]() |
Re: [2008] Can I add a TCPClient Component
ok ur code is perfect, just what i wanted
now i have few questions: 1) Im getting an error Cross-thread operation not valid: Control 'LblConnection' accessed from a thread other than the thread it was created on. when I did this: Code:
Private Sub MessageReceived(ByVal sender As ConnectedClient, ByVal Message As String) 'A message has been received from one of the clients. 'To determine who its from, use the sender object. 'sender.SendMessage can be used to reply to the sender.
Select Case Message
Case "/Connect"
sender.SendMessage("/Connected")
LblConnection.Text = "Connected"
Case Else
txtMain.Text = txtMain.Text & Message & vbNewLine
End Select
End Sub
how can I send more msgs from the server how can I reiceive more msgs on the client ur code seems only to work for the first msg?? thx |
|
|
|
|
|
#17 |
|
Networker
Join Date: Aug 05
Location: Sweden
Posts: 7,328
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() |
Re: [2008] Can I add a TCPClient Component
1.
That is because all socket code is running on a separate thread, in order to access the controls you need to use Invoke. Heres an example that will fix the problem you posted: VB.Net Code:
VB.Net Code:
VB.Net Code:
2. If you want to send messages from the server, simply iterate through the list of connected clients and call the SendMessage method on the client you want to send a message to. EDIT: Oh, I see that I've made a silly misstake in my code. Try it now.
__________________
---My Flickr photo stream. Have a look! Rate posts that helped you. I do not reply to PM's with coding questions. How to Get Your Questions Answered LINQ examples | Save/load a forms layout | TCP client/server connection | Retrieving the EventHandler for any Event by code. Check out the work in progress: Obtuze - A Neural Network for OCR Last edited by Atheist; Jan 2nd, 2008 at 03:29 PM. |
|
|
|
|
|
#18 |
|
Addicted Member
Join Date: Dec 07
Posts: 166
![]() |
Re: [2008] Can I add a TCPClient Component
well.. can u elaborate more?
Code:
Private Sub BtnSend_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BtnSend.Click
If txtSend.Text <> "" Then
' ????? should i use client.?????
End If
End Sub
|
|
|
|
|
|
#19 |
|
Frenzied Member
Join Date: Mar 06
Location: Pennsylvania
Posts: 1,069
![]() |
Re: [2008] Can I add a TCPClient Component
Elaborate more? He just told you exactly what to do. What are you having problems with?
|
|
|
|
|
|
#20 |
|
Addicted Member
Join Date: Dec 07
Posts: 166
![]() |
Re: [2008] Can I add a TCPClient Component
how to iterate through the list of connected clients ...
sorry but its really not easy for me |
|
|
|
|
|
#21 |
|
Networker
Join Date: Aug 05
Location: Sweden
Posts: 7,328
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() |
Re: [2008] Can I add a TCPClient Component
You see, this is a collection:
VB.Net Code:
VB.Net Code:
__________________
---My Flickr photo stream. Have a look! Rate posts that helped you. I do not reply to PM's with coding questions. How to Get Your Questions Answered LINQ examples | Save/load a forms layout | TCP client/server connection | Retrieving the EventHandler for any Event by code. Check out the work in progress: Obtuze - A Neural Network for OCR |
|
|
|
|
|
#22 |
|
Addicted Member
Join Date: Dec 07
Posts: 166
![]() |
Re: [2008] Can I add a TCPClient Component
i have another question
when i send a msg from the client to the server using this code Code:
Private Sub SendMessage(ByVal Msg As String)
Dim sw As IO.StreamWriter
Try
sw = New IO.StreamWriter(client.GetStream)
sw.Write(msg)
sw.Flush()
Catch ex As Exception
MessageBox.Show(ex.ToString)
End Try
End Sub
its like this, firsrt the two programs connect and the client send "/connect" and the server recieves it, then whatever the client sends the server doesnt recieve it. the third msg is recieved, the fourth is not.... why is this happeneing? 2) how to read msgs in the client program?? my client only sends now... should I create a Public Class ConnectedClient in the client program also? Last edited by perito; Jan 3rd, 2008 at 11:33 AM. |
|
|
|
|
|
#23 |
|
Networker
Join Date: Aug 05
Location: Sweden
Posts: 7,328
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() |
Re: [2008] Can I add a TCPClient Component
About your first question, it was a small misstake I had made in the code that is now fixed, I've edited the original code in my previous post.
As for your second question, I cant see how I forgot to add that, hold on..
__________________
---My Flickr photo stream. Have a look! Rate posts that helped you. I do not reply to PM's with coding questions. How to Get Your Questions Answered LINQ examples | Save/load a forms layout | TCP client/server connection | Retrieving the EventHandler for any Event by code. Check out the work in progress: Obtuze - A Neural Network for OCR |
|
|
|
|
|
#24 |
|
Networker
Join Date: Aug 05
Location: Sweden
Posts: 7,328
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() |
Re: [2008] Can I add a TCPClient Component
There, I've edited the code to handle incoming messages on the client side.
__________________
---My Flickr photo stream. Have a look! Rate posts that helped you. I do not reply to PM's with coding questions. How to Get Your Questions Answered LINQ examples | Save/load a forms layout | TCP client/server connection | Retrieving the EventHandler for any Event by code. Check out the work in progress: Obtuze - A Neural Network for OCR |
|
|
|
|
|
#25 |
|
Addicted Member
Join Date: Dec 07
Posts: 166
![]() |
Re: [2008] Can I add a TCPClient Component
handling incoming messages worked perfectly... but am I blind because I cant see any difference in the rest of the code?
what should I chage to stop sending the msg twice before it was read? |
|
|
|
|
|
#26 | |
|
Networker
Join Date: Aug 05
Location: Sweden
Posts: 7,328
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() |
Re: [2008] Can I add a TCPClient Component
Quote:
__________________
---My Flickr photo stream. Have a look! Rate posts that helped you. I do not reply to PM's with coding questions. How to Get Your Questions Answered LINQ examples | Save/load a forms layout | TCP client/server connection | Retrieving the EventHandler for any Event by code. Check out the work in progress: Obtuze - A Neural Network for OCR |
|
|
|
|
|
|
#27 |
|
Addicted Member
Join Date: Dec 07
Posts: 166
![]() |
Re: [2008] Can I add a TCPClient Component
THANKS...............
thanks a million, the program works fine now I still have a couple questions to improve the code now :P first, on the server side, how to see the ConnectedClient List? (for example put it in ListBox1) so we can send seperate msgs? thanks agian |
|
|
|
|
|
#28 |
|
Networker
Join Date: Aug 05
Location: Sweden
Posts: 7,328
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() |
Re: [2008] Can I add a TCPClient Component
Well, since you dont have any good unique identifier like a username or something of the sort, you have 3 options:
1. Simply add each ConnectedClient instance in the collection to the Listbox, since the listbox can have any kind of object added to it. This wont be pretty as each item will look the same in the listbox..something like this: [ProjectName].UserConnection The only advantage is that the listbox will return a ConnectedClient in the SelectedItem property that you can use easily: VB.Net Code:
2. This is another option: VB.Net Code:
VB.Net Code:
3. The final option: This is the best option if you want to be able to identify a specific client from the rest. Upon connection, have the client send a username that it wants to use. The server receives the username, checks so that it isnt already in use, then assigns it to the instance of ConnectedClient from which the message was received. This username can then be used to display every client in a list.
__________________
---My Flickr photo stream. Have a look! Rate posts that helped you. I do not reply to PM's with coding questions. How to Get Your Questions Answered LINQ examples | Save/load a forms layout | TCP client/server connection | Retrieving the EventHandler for any Event by code. Check out the work in progress: Obtuze - A Neural Network for OCR |
|
|
|
|
|
#29 |
|
Addicted Member
Join Date: Dec 07
Posts: 166
![]() |
Re: [2008] Can I add a TCPClient Component
ok so Im tring to build the third option
so I have this code Code:
Private Sub MessageReceived(ByVal sender As ConnectedClient, ByVal Message As String) 'A message has been received from one of the clients. 'To determine who its from, use the sender object. 'sender.SendMessage can be used to reply to the sender.
If Mid(Message, 1, 1) = "/" Then
Select Case Mid(Message, 2, 8)
Case "Connect:"
sender.SendMessage("/Connected")
SetConnectionLabelText("Connected")
Case Else
WriteToMainText(Message)
End Select
End If
End Sub
how to add the username to the list? I was checking ur previous topic and u had a different diclaration Dim Clients As New Dictionary(Of String, Net.Sockets.TcpClient) whats the difference? and u added the name in DoListen Sub not MessageReceived Sub? what should I do? |
|
|
|
|
|
#30 | |
|
Networker
Join Date: Aug 05
Location: Sweden
Posts: 7,328
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() |
Re: [2008] Can I add a TCPClient Component
Quote:
Heres a method of handling messages used in MSDN 101 examples: Send the messages with the | character as separator. If the user wants to connect with a username he'd send this: "CONNECT|MyName" Your messageReceived method would then look like this: VB.Net Code:
About my use of the Dictionary in the other example, it provides the functionallity to store items in a collection and let each item have a (in this case) string key to identify them. We could've used that in this code aswell, but I chose the List instead. Also, ignore all my other code in that example, the examples in there are fairly simple and nothing you should be using.
__________________
---My Flickr photo stream. Have a look! Rate posts that helped you. I do not reply to PM's with coding questions. How to Get Your Questions Answered LINQ examples | Save/load a forms layout | TCP client/server connection | Retrieving the EventHandler for any Event by code. Check out the work in progress: Obtuze - A Neural Network for OCR |
|
|
|
|
|
|
#31 |
|
Lively Member
Join Date: May 07
Posts: 87
![]() |
Re: [2008] Can I add a TCPClient Component
Hey there i did something like atheist did 2.
I personaly did it with creating a new class wich has as property ConnectedClient or a connected socket or something.(notice i worked with winsock so my own class had a connected winsock class in it) This way you can store anything you like from that user even if you want (while making a game) its position in your screen/world. Greets |
|
|
|
|
|
#32 |
|
Addicted Member
Join Date: Dec 07
Posts: 166
![]() |
Re: [2008] Can I add a TCPClient Component
ok, first in the above code we did
Code:
Private Sub DoListen()
Dim incomingClient As System.Net.Sockets.TcpClient
Do
incomingClient = listener.AcceptTcpClient 'Accept the incoming connection. This is a blocking method so execution will halt here until someone tries to connect.
Dim connClient As New ConnectedClient(incomingClient) 'Create a new instance of ConnectedClient (check its constructor to see whats happening now).
' clients.Add(New ConnectedClient(incomingClient)) 'Adds the connected client to the list of connected clients.
clients.Add(connClient) 'Adds the connected client to the list of connected clients.
AddHandler connClient.dataReceived, AddressOf Me.MessageReceived
Loop
End Sub
could u tell me how to create a string variable for holding the username in the ConnectedClient class, and create a string property for it... thanks |
|
|
|
|
|
#33 | |
|
Networker
Join Date: Aug 05
Location: Sweden
Posts: 7,328
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() |
Re: [2008] Can I add a TCPClient Component
Quote:
I'll edit the original code in my above post. Watch it closely ![]() EDIT: There, take a look at the code for the ConnectedClient class, specificly at the mUsername variable and the Username property.
__________________
---My Flickr photo stream. Have a look! Rate posts that helped you. I do not reply to PM's with coding questions. How to Get Your Questions Answered LINQ examples | Save/load a forms layout | TCP client/server connection | Retrieving the EventHandler for any Event by code. Check out the work in progress: Obtuze - A Neural Network for OCR Last edited by Atheist; Jan 3rd, 2008 at 01:40 PM. |
|
|
|
|
|
|
#34 |
|
Addicted Member
Join Date: Dec 07
Posts: 166
![]() |
Re: [2008] Can I add a TCPClient Component
Excelent!
So now, each time a new client connects to my server, its username will be added to the listbox lbClients How to send a msg to a specific Client (the one which is selected in the list box?) thanks |
|
|
|
|
|
#35 |
|
Fanatic Member
Join Date: Jul 07
Posts: 529
![]() |
Re: [2008] Can I add a TCPClient Component
@perito
Can You Post Your Full Code That is Working For You Now I am also interested |
|
|
|
|
|
#36 |
|
Addicted Member
Join Date: Dec 07
Posts: 166
![]() |
Re: [2008] Can I add a TCPClient Component
@killer7k
sure Ill post the code when I finish the program although this is pretty much it http://www.vbforums.com/showpost.php...2&postcount=14 anyway, to all moderators and admins PLEASE could you make this topic sticky or add it to the tut sections u cant edit it if u want, but I kept searching for 4 days before atheist started helping me. Before his help, I couldnt find anything, everything on the web is 100x more complicated. If anyone could turn this thread to a tut, that would be great !! Please give credits to Atheist if u do so. Thanks @Atheist could u plz reply to my previous question? |
|
|
|
|
|
#37 |
|
Fanatic Member
Join Date: Jul 07
Posts: 529
![]() |
Re: [2008] Can I add a TCPClient Component
oK Thanks m8
|
|
|
|
|
|
#38 | |
|
Networker
Join Date: Aug 05
Location: Sweden
Posts: 7,328
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() |
Re: [2008] Can I add a TCPClient Component
Quote:
You use the GetClientByName function to get the ConnectedClient instance connected to the username. Once you have it, call its SendMessage method.
__________________
---My Flickr photo stream. Have a look! Rate posts that helped you. I do not reply to PM's with coding questions. How to Get Your Questions Answered LINQ examples | Save/load a forms layout | TCP client/server connection | Retrieving the EventHandler for any Event by code. Check out the work in progress: Obtuze - A Neural Network for OCR |
|
|
|
|
|
|
#39 |
|
Addicted Member
Join Date: Dec 07
Posts: 166
![]() |
Re: [2008] Can I add a TCPClient Component
OK, it worked gr8
Now how to figure out if a client disconnected from my server? thx |
|
|
|
|
|
#40 | |
|
Networker
Join Date: Aug 05
Location: Sweden
Posts: 7,328
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() |
Re: [2008] Can I add a TCPClient Component
Quote:
However, if the client closes because of the system crashing or something of the sort, sending a message is obviously not possible. We will solve this by adding some nifty code when the exception occures in the doRead subroutine. But in order to do this we will need to change the ConnectedClients constructor, I'm going to update the code again.. Edit: There now I've edited the code. Notice the new constructor in the ConnectedClient class, it takes one more argument, an the instance of Form1. So upon creating a new ConnectedClient class, (on the doListen subroutine) we pass it like so: New ConnectedClass(incomingClient, Me) This is because we want to call the new subroutine 'removeClient' from within ConnectedClass, like you can see being done in the doRead subroutine. I hope this isnt too confusing for you
__________________
---My Flickr photo stream. Have a look! Rate posts that helped you. I do not reply to PM's with coding questions. How to Get Your Questions Answered LINQ examples | Save/load a forms layout | TCP client/server connection | Retrieving the EventHandler for any Event by code. Check out the work in progress: Obtuze - A Neural Network for OCR Last edited by Atheist; Jan 4th, 2008 at 09:10 AM. |
|
|
|
|
![]() |
|
||||||
| Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
| Thread Tools | Search this Thread |
| Display Modes | |
|
|