[02/03] Chat Program help please!
Alright im about to completely lose my mind here, i cant for the life of me get this thing to communicate back and forth current code is
Code:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
listener = New TcpListener(Net.IPAddress.Any, 32111)
listener.Start()
listenThread = New Threading.Thread(AddressOf DoListen)
listenThread.IsBackground = True
listenThread.Start()
txtChat.Text = "Server Started"
userBox.Items.Add(userName.Text)
End Sub
'Server listening
Private Sub DoListen()
Dim sr As StreamReader
Dim sw As StreamWriter
Do
Try
Dim client As Net.Sockets.TcpClient = listener.AcceptTcpClient
sr = New StreamReader(client.GetStream)
Dim username As String = sr.ReadToEnd
userBox.Items.Add(username)
sw = New StreamWriter(client.GetStream)
sw.Write(userBox.Items)
sw.Close()
client = New TcpClient
sr = New StreamReader(client.GetStream)
userBox.Items.Add(sr)
Catch
End Try
Loop
End Sub
'Client Connect
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
Dim client As New TcpClient
Dim sw As StreamWriter
client.Connect("127.0.0.1", 32111)
sw = New StreamWriter(client.GetStream)
sw.Write(userName.Text)
sw.Close()
End Sub
End Class
the bold part is the area im working on, i cant get the server to return a the currently connected clients list to the client, and i cant figure out how to get the client and server to talk for that matter. i feel like im missing a crucial piece here, like how does the stream reader know what stream its reading? I really need some help, ive used my whole entire day to day doing nothing but trying to get this working, please help me...
Re: [02/03] Chat Program help please!
Re: [02/03] Chat Program help please!
Since it's TCP, in which my knowledge is seriously dated, the way I would go about this is to search for TCPListener and the user Atheist, as I feel that he has the most complete TCP examples on the forum. If it were UDP, I'd send you to the classes I posted in the networking forum, but that's a different animal.
In general, what you have written looks almost reasonable, except that you appear to be adding things to what I take to be a Listbox (userbox), which you can't do directly from a background thread, since controls are all on the UI thread. You'd need to access the control via a delegate. JM has a thorough tutorial on this in his signature, so it isn't worth repeating (if you don't know who JM is, I would have to figure out how to spell it, but he's the second most prolific poster on the entire VBF, and the most prolific in the .NET forum).
Since you say that you are having trouble connecting, is it safe to assume that if you put a breakpoint in that DoListen sub just after the AcceptTCPClient line that it would never be reached? I guess that should be safe, since if userbox is indeed a control, an IllegalCrossThreading exception would be thrown when you reached that line.
The code all looks like it is part of a single program, which may not be true at all. I had to adjust a setting to have my UDP class communicate with other processes within the same computer. Not sure if that is relevant in your case, but every time I have used TCP it has been between devices, not on the same system.
Re: [02/03] Chat Program help please!
If client and server are on the same system, look into this:
SetSocketOption(Net.Sockets.SocketOptionLevel.Socket, Net.Sockets.SocketOptionName.ReuseAddress, True)
It's what I needed to use UDP to communicate on the same system, and it seems like it would apply to TCP, as well.
Re: [02/03] Chat Program help please!
ive checked out atheist thread and my biggest problem is that im doing this in to 2003, where LIST OF does not exist, so it completely blows alot of the examples he has since it seem to rely heavily on this.(most of what has been written has been off of his example) yes this is all one program for host and client, the difference being what button is pushed. I have client connecting to server, so the connection is happening, but i just cant get them to communicate after that point. Once conencted i need the server to send a "Currently connected clients list" to the client, but i think my biggest problem is i dont quite understand the process of streamreader and streamwriter.
thanks for point out delegate, ill have to look into that.
Re: [02/03] Chat Program help please!
That's true, you did say 02/03. I have never used TCP to connect with another process on the same system. However, the TCP code I wrote was for 2003, so the class may be of some use to you. I wrote it many years ago, though, and my memory of that is fuzzy.
Since I'm on the right computer, here are the two classes that I was using for communicating via TCP to a PDA. I think it will require two posts. Here's the first one:
Code:
Public Class PDAviaTCP
Private curListen As System.Net.Sockets.TcpListener
Private quitFlag As Boolean
Private myTimer As System.Windows.Forms.Timer
Private lSock As System.Net.Sockets.TcpClient
Private netStream As System.Net.Sockets.NetworkStream
Private linOpt As System.Net.Sockets.LingerOption
Private bTimedOut As Boolean
#Region "Constructors and Destructors"
Public Sub New()
curListen = New System.Net.Sockets.TcpListener(System.Net.IPAddress.Any, 2123)
quitFlag = True
'Create the timer
myTimer = New System.Windows.Forms.Timer
'Need to tell it where to send time tick messages.
AddHandler myTimer.Tick, AddressOf TimerEventProcessor
'This is set so that we can know the status if nothing is received.
bTimedOut = False
' Sets the timer interval to 5 seconds.
myTimer.Interval = 5000
myTimer.Enabled = False
linOpt = New System.Net.Sockets.LingerOption(True, 5)
End Sub
Public Sub dispose()
myTimer.Dispose()
curListen.Stop()
If Not lSock Is Nothing Then
lSock.Close()
End If
End Sub
#End Region
#Region "Public Functions"
'StartListening puts the TCPListener class into listening mode. This must be called
'for a connection to be received.
Public Sub StartListening()
Try
curListen.Start()
Catch ex As Exception
'Regardless of the exception, this may be ok.
MsgBox("Exception was thrown during start." & vbNewLine & vbNewLine & ex.Message, MsgBoxStyle.Information, "Possible Issue")
End Try
End Sub
'This function simply checks for a connection, but does not do anything except return
'true if a connection is pending.
Public Function CheckForConnection() As Boolean
Try
CheckForConnection = curListen.Pending
Catch
CheckForConnection = False
End Try
End Function
'This function simply accepts the connection and stops the listener.
Public Function GetConnection() As Boolean
Try
If curListen.Pending Then
lSock = curListen.AcceptTcpClient
lSock.LingerState = linOpt
netStream = lSock.GetStream
curListen.Stop()
GetConnection = True
Else
GetConnection = False
End If
Catch ex As Exception
GetConnection = False
End Try
End Function
'Stops listening without bothering with whether or not a connection is available.
Public Sub StopListening()
curListen.Stop()
End Sub
'Use this to send data to the socket. No check is made to see that
'the socket is available. The return is false if any exceptions are raised.
Public Function SendData(ByVal st1 As String) As Boolean
Dim sendBuff(1024) As Byte
Try
sendBuff = System.Text.Encoding.Default.GetBytes(st1.ToCharArray())
netStream.Write(sendBuff, 0, sendBuff.GetLength(0))
SendData = True
Catch ex As Exception
SendData = False
End Try
End Function
'Use this to get data from the socket. This will time out in 5s.
Public Function RetrieveData() As String
Dim recBuff(1024) As Byte
Dim recCount As Integer
Dim st1 As String
Dim hasRead As Boolean
hasRead = False
'Get ready to read.
quitFlag = True
myTimer.Enabled = True
Try
Do While quitFlag
If netStream.DataAvailable Then
recCount = netStream.Read(recBuff, 0, recBuff.GetLength(0))
End If
If recCount > 0 Then
hasRead = True
myTimer.Enabled = False
'Turn it into a string.
st1 &= System.Text.Encoding.ASCII.GetString(recBuff, 0, recCount)
'Clear out the buffer.
recBuff.Clear(recBuff, 0, recBuff.GetLength(0))
recCount = 0
Else
'If hasRead is set, then something has been received, but the last loop
'returned nothing. Therefore, we are done reading.
If hasRead Then
'This is simply cleared to stop the loop.
quitFlag = False
End If
'DoEvents, but only if nothing is coming in!
Application.DoEvents()
End If
Loop
Catch ex As Exception
'Nothing can be done here, but that's ok.
MsgBox(ex.Message)
End Try
'Get out.
myTimer.Enabled = False
Me.bTimedOut = False
RetrieveData = st1
End Function
'If this is true, then the time event fired. Basically, this means that if
'RetrieveData() returned an empty string, it was because of timing out.
Public Function TimedOut() As Boolean
TimedOut = Me.TimedOut
End Function
#End Region
#Region "Private Functions"
'The timer is used to stop the endless loop in RetrieveData(), and for no other
'purpose. If the event fires, the bTimedOut variable is set.
Private Sub TimerEventProcessor(ByVal myObject As Object, ByVal myEventArgs As EventArgs)
myTimer.Enabled = False
quitFlag = False
Me.bTimedOut = True
End Sub
#End Region
End Class
Re: [02/03] Chat Program help please!
And here's the second one. Keep in mind that this is not truly client server in the sense you are using, because a PDA to a desktop is never more than a single connection at a time, which is somewhat simpler.
Code:
Public Class ThreadedConnection
Implements IDisposable
Private theThread As System.Threading.Thread
Private mDBHolder As dbHolder
Private mPDAvia As PDAviaTCP
Private Shared mWriteDone As System.Threading.ManualResetEvent
Private waitTimer As System.Windows.Forms.Timer
Private mStarted As Boolean
#Region "Constructors and Destructors"
Public Sub New(ByRef dbL As dbHolder)
'The function for the thread.
theThread = New System.Threading.Thread(AddressOf DoConnection)
mStarted = False
'This may be somewhat sketchy, but it should work just fine.
mDBHolder = dbL.Copy
theThread.IsBackground = True
mPDAvia = New PDAviaTCP
mWriteDone = New System.Threading.ManualResetEvent(False)
waitTimer = New System.Windows.Forms.Timer
'Need to tell it where to send time tick messages.
AddHandler waitTimer.Tick, AddressOf TimerEventProcessor
waitTimer.Interval = 5000
waitTimer.Enabled = False
End Sub
Public Sub Dispose() Implements System.IDisposable.Dispose
StopConnection()
mWriteDone.Close()
mPDAvia.dispose()
mDBHolder.Dispose()
End Sub
#End Region
#Region "Properties"
Public ReadOnly Property ImStarted() As Boolean
Get
ImStarted = mStarted
End Get
End Property
#End Region
#Region "Public Functions"
'This checks the database in the connection thread, and if it is valid, the thread
'is started.
Public Function StartConnection() As Boolean
If mDBHolder.IsValid Then
theThread.Start()
End If
StartConnection = mDBHolder.IsValid
End Function
Public Sub StopConnection()
'First, start the timer, just in case.
waitTimer.Enabled = True
Try
'The event will be signaled (go ahead) throughout, with the exception of writing
'to the db. For that alone it will be unsignaled (wait). Once the write is complete
'the event will be signaled.
mWriteDone.WaitOne()
'At which point, it would be a good idea to stop the comport from listening.
mPDAvia.StopListening()
'And end the thread.
theThread.Abort()
Catch ex As Exception
'An error could arise, since the last two steps may be completed in the timer
'event. However, the exception is unexceptional, and can be safely ignored.
End Try
End Sub
#End Region
#Region "Private Functions"
Private Sub DoConnection()
Dim st1 As String
Dim st2 As String
Dim v As Integer
Dim outData As String
Dim mFlag As Boolean
Dim cnt As Integer
Dim stHold(30) As String
'First make the string data for outputting.
mPDAvia.StartListening()
mWriteDone.Set()
Do
mStarted = True
Do
Application.DoEvents()
Loop While Not mPDAvia.CheckForConnection
outData = mDBHolder.CreateData()
'If you get here, then a connection is ready.
If mPDAvia.GetConnection() Then
'Send the type info across.
mPDAvia.SendData("1")
st1 = mPDAvia.RetrieveData
'Next, send out the output data.
mPDAvia.SendData(outData)
'Now, st1 holds either 1 (no data) or 4 (new data coming) or 5 (all data coming)
v = CInt(Val(st1))
If v > 1 Then
'Now the data coming back should be received.
theThread.Sleep(1000)
st2 = ""
cnt = 0
Do
st1 = mPDAvia.RetrieveData
stHold(cnt) = st1
cnt += 1
If st1 = "DONE" Then
mPDAvia.SendData("2")
st1 = ""
Else
mPDAvia.SendData("1")
st2 &= st1
End If
Loop While st1 <> ""
'MsgBox(st2.Length)
mWriteDone.Reset()
mFlag = mDBHolder.UpdateTablesWithXML(st2)
If mFlag Then
v = 2
End If
mPDAvia.SendData(v.ToString)
mWriteDone.Set()
If mFlag Then
Windows.Forms.MessageBox.Show("Tables were successfully updated from the PDA.", "All is Well", MessageBoxButtons.OK, MessageBoxIcon.Information)
End If
End If
End If
'Now it is necessary to start listening again.
mPDAvia.StartListening()
Loop While True
End Sub
Private Sub TimerEventProcessor(ByVal myObject As Object, ByVal myEventArgs As EventArgs)
waitTimer.Enabled = False
'this is the same as the stop connection, but no more waiting.
Try
mWriteDone.Set()
mPDAvia.StopListening()
theThread.Abort()
Catch ex As Exception
'An exception here is unlikely, but it should be ignored.
Finally
Windows.Forms.MessageBox.Show("Thread timer timed out. This message is not the best thing to see, but means that a safety net is working.", "OK Message", MessageBoxButtons.OK, MessageBoxIcon.Information)
End Try
End Sub
#End Region
End Class
Re: [02/03] Chat Program help please!
ok, well i have a couple questions here. Whats the difference between using networkstream vs streamreader/streamwriter. Also whats the process of doing a stream? do you have to make an new connection every time you do a stream? the send data code in the server seems like it would work for what im trying to do, but i just cant figure out how to read the data the send data is sending.
Re: [02/03] Chat Program help please!
Actually, since that was written at least four years ago, I have little memory of the whole thing. I don't know why I stumbled across NetworkStream, nor what the difference is. From what I see, the TCPClient has a networkstream as a member, which is what I obtained. Therefore, I would guess that you don't need a new connection, because the stream is associated with the TCPClient class. As long as the TCPClient class is valid, the stream should be.
However, since I mostly deal with UDP rather than TCP, I am not even close to an expert on the subject.
Re: [02/03] Chat Program help please!
ok newest code is as follows
Code:
Imports System.Net.Sockets
Imports System.Net
Imports System.Threading
Imports System.IO
Public Class Form1
Inherits System.Windows.Forms.Form
Dim listener As TcpListener
Dim listenThread As Thread
Dim clientlist As New ListBox
Dim server As New TcpClient
Dim client As New TcpClient
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
listener = New TcpListener(IPAddress.Any, 32111)
listener.Start()
listenThread = New System.Threading.Thread(AddressOf dolisten)
listenThread.IsBackground = True
listenThread.Start()
txtChat.Text = "Server Started"
clientlist.Items.Add(userName.Text)
userList.Items.Add(userName.Text)
End Sub
Private Sub dolisten()
Dim sr As StreamReader
Do
Try
server = listener.AcceptTcpClient
sr = New StreamReader(server.GetStream)
Dim name As String = sr.ReadToEnd
Call fillclientlist(name)
Catch
End Try
Loop
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
Dim sw As StreamWriter
client.Connect("127.0.0.1", 32111)
sw = New StreamWriter(client.GetStream)
sw.Write(userName.Text)
sw.Flush()
sw.Close()
End Sub
Private Sub fillclientlist(ByVal userName As String)
clientlist.Items.Add(userName)
userList.Items.Clear()
For Each item As String In clientlist.Items
Dim sw As StreamWriter
sw = New StreamWriter(server.GetStream)
sw.Write(item)
sw.Flush()
sw.Close()
Dim sr As StreamReader
---> sr = New StreamReader(client.GetStream)
userList.Items.Add(sr.ReadToEnd)
Next
End Sub
End Class
This seems like it should work, but it kicks an error where the arrow is. Error : Operation not allowed on non-connected sockets.
Re: [02/03] Chat Program help please!
Re: [02/03] Chat Program help please!
*bump again* Ive searched all over these forums, and the net and just cant find the answer to this, i cant be that far off i just need some guidance in the right direction here.
Re: [02/03] Chat Program help please!
So you press Button1 to set up the listener and start the background thread. Do you then press Button2 to connect the client? I assume so, as it is the connection acceptance that should trigger the call to fillClientList. However, when you get to that point, there are a couple of things you might do. Streams can get a bit odd in that they have a streampointer. Where is that pointer located? After the read, it would be at the end, but I'd have to look it up to be certain where it is located after the write. So you might need to move the pointer back to the beginning of the stream, since you wrote the stream out in the Button2 event. That seems like it would raise a different exception, though.
The other thing I note is that you are filling a listbox in the very next line, even though you are in a background thread, so you should get an IllegalCrossReference exception if you even got that far, but you didn't, so that's not the problem.
I see no particular reason why the connection should have closed, but then again, I don't deal with connections often. Put a breakpoint on the line (or wait for the exception to pause execution) and take a look at the Client. Is the connection closed? If so, then put a breakpoint in the first line of Button2 and step through that code watching Client. You are looking for when it closes. Closing the stream doesn't seem like it would close the connection, but, again, I'm not all that familiar with connections.
Re: [02/03] Chat Program help please!
hey is it possible that the client is connecting to the server but the server is not connecting to the client?
Re: [02/03] Chat Program help please!
No. There either is a connection or there isn't. If listener.AcceptTCPClient returns something then you have a connection.
Re: [02/03] Chat Program help please!
well none of this makes any since cause i cant get the client and server to talk back and forth...
Re: [02/03] Chat Program help please!
I do remember having issues with connections timing out fast, but not nearly fast enough to be causing the troubles you are having.
Have you tried what I suggested with the breakpoints in post #13? That's where I'd start to diagnose the problem. I have some suspicion that the error message you are getting is not quite accurate, but you'd need to confirm that Client is connected when the error arises. If it isn't, then you'd need to see when it stopped being connected, because it sure seems like it must have been at one time.
Re: [02/03] Chat Program help please!
might be a bit of a dumb question here, but how can i tell that its connected, only reason i can tell its connecting is that it gives me the username, and i can also get two different programs to connect.
i can tell you that as soon as i hit the fillclientlist sub routine my variables only show the userName variable, but that may be because im passing it...
Re: [02/03] Chat Program help please!
Yeah, you're passing it. I'm on the wrong computer to really look this up (I only have 2005 on this one), but it looks like you want to look at the Connected property. Therefore, when you hit the breakpoint, highlight Client and press SHift+F9 to look at the properties in a leisurely manner (the tooltip is often too unstable for easy perusing), and take a look at that property. It should be True, and if it is, then the next thing I would do would be to look at the streamreader (either sr, or the stream property of Client), and look at the Position property. I think that should be 0, or something like that. If it isn't, then you will have a problem because you will be reading when the stream is at an end. Streams read from the current position, and they don't automatically reset the position to the start of the stream.
Re: [02/03] Chat Program help please!
Can someone post a project file here? i really need this :) Pm me