Morning All,
I have been writing an ever so simple IRC client in visual basic. I have a niggly issue whereby when I am writing to the network stream. On other clients my message cuts off after the first space character. I'm sure this is something simple as the messages are being sent, receiving is fine and debugging the issue it wherever I read the message (i.e. if I debug.print the message being written to the stream it still includes all the words and spaces.) Here is my code.
Thanks in advance
'Send data to IRC Server
Sub Send(ByVal message)
Try
'Reformat message to IRC command
message = message & vbCrLf
Debug.Print(message)
'Convert message string into bytes
Dim sendBytes As [Byte]() = Encoding.ASCII.GetBytes(message)
'Write data to stream
ircStream.Write(sendBytes, 0, sendBytes.Length)
'Run test to see if the string sent matches the user input
Dim messageSent As String = Encoding.ASCII.GetString(sendBytes)
Debug.Print(messageSent)
'Display message on the screen( 0 = Sent Formatting )
PrintToScreen(message, 0)
Catch ex As Exception
'Catch error and display error message in the debug console
Debug.Print("Error Sending")
End Try
End Sub
You probably just need to prepend a ':' to your message like so...
PRIVMSG #chan_name :your message with spaces
By flushing, calling the flush function of the stream... Which (if I remember correctly) clears the data in the buffer, and writes it at the same time.
ircStream.Flush()
Related
I am trying to write an asynchronous TCP client with VB.NET to communicate with a thermal printer (Intermec Px4e), but I am facing an issue regarding the way I receive the data from it.
Previously I was using a synchronous client, but I had the problem regarding the response not coming instantly from the printer, so after sending data and then checking for available bytes I was able to read only the first bytes of the response.
This is the synchronous client I am actually using:
Private Function sendBytesEthernet(ByVal data As Byte(), ByVal withResponse As Boolean) As PrinterPacket(Of Byte())
Dim socketStatus As Net.Sockets.SocketError
Dim response As New PrinterPacket(Of Byte()) With {.StatusCode = CommandStatusCode.ERR, _
.Response = String.Empty, _
.Data = data}
Try
If Me.oggettoSocket.Client.Poll(2000, Sockets.SelectMode.SelectWrite) Then
Me.oggettoSocket.Client.Send(data, 0, data.Length, 0, socketStatus)
Else
Throw New Exception(socketStatus.ToString())
End If
If withResponse Then
Dim bytesAvailable As UInteger = Me.oggettoSocket.Available
If bytesAvailable > 0 Then
Dim dataBuffer(bytesAvailable - 1) As Byte
Dim bytesReceived As UInteger = Me.oggettoSocket.Client.Receive(dataBuffer, 0, dataBuffer.Length, Sockets.SocketFlags.None, socketStatus)
If socketStatus = Sockets.SocketError.Success Then
If bytesReceived > 0 Then
response.Response = System.Text.Encoding.UTF8.GetString(dataBuffer)
response.StatusCode = CommandStatusCode.OK
Return response
End If
Else
Throw New Exception(socketStatus.ToString())
End If
End If
End If
If socketStatus = Sockets.SocketError.Success Then
response.StatusCode = CommandStatusCode.OK
Else
Throw New Exception(socketStatus.ToString())
End If
Catch ex As Exception
Select Case ex.Message
Case "ConnectionReset"
Me.oggettoSocket.Client.Disconnect(True)
Me.openSocket()
End Select
response.Response = ex.Message
End Try
Return response
End Function
What happens is that If send a command to the printer that involves a big response from it, I receive the full response splitted in several packets, so with this function I am only able to read the first packet.
For example:
I send to the printer the command to list all the fonts available (FONTS[CRLF])
The printer responds, but it sends the first 54 bytes and then truncates the list.
The printer sends the second packet, this time 1560 bytes long, but it still truncates the list.
Lastly the printer completes the list with last 25 bytes.
Basically with my function I am only able to read the first 54 bytes, unless I don't use a loop to check the availability on the receive buffer in conjunction with a Thread.Sleep() call, since the client is synchronous and I have to wait for the printer to send every packet, but I find this method really inefficient.
At this point I concluded that I had to move to an asynchronous approach, due to the nature of the TCP protocol. I copied an example of async client on the MSDN and it works, but it doesn't fit my use case. Why?
Because I actually have a thread that constantly communicate with the printer through the socket, and I open the connection when the thread starts and close it when the thread ends. If use, for example, the BeginReceive callback used in the MSDN example, that call will never end until I close the connection client side. This cannot take place, since I keep the connection open to the printer and I can't establish a new TCP connection for every thread cycle (that would be a waste in terms of network traffic).
I hope I have explained the problem well.
I have a named pipes server running on a workstation. When the server receives a message I am able to process it. The problem is several messages can be sent at the same time. The server processes the first message but the remaining messages are lost. Not sure how to listen for multiple messages. I cannot batch the messages into one message as I need to have the server respond to each and every message separately. Does anyone know how I can accomplish this. My server code is below which is running in a thread.
Dim Pipe As New Pipes.NamedPipeServerStream("bellhop", Pipes.PipeDirection.InOut, -1, Pipes.PipeTransmissionMode.Message, Pipes.PipeOptions.Asynchronous)
While BellhopExiting = False
Pipe.WaitForConnection()
Dim Reader As New StreamReader(Pipe)
Dim XML As String = Reader.ReadLine
If XML IsNot Nothing Then
Dim Writer As New StreamWriter(Pipe)
Writer.AutoFlush = True
Try
ParseXML(XML)
'Send a success acknowledgement back to the sender.
Writer.WriteLine("Message Delivered")
Catch ex As Exception
'Send a failed acknowledgement back to the sender.
Writer.WriteLine("Failed->Bellhop->WaitForConnection->Computer: " & ComputerName & " Error: " & ex.Message)
End Try
End If
Pipe.Disconnect()
End While
I have a project in Visual Studio 2005 with EMDK 2.6 with a MC1000 data collector over XP SP3 implemented on Windows CE.
I have this function within the project that gives me an error that I can't solve :
'Handle data from the reader
Private Sub HandleData(ByVal TheReaderData As Symbol.Barcode.ReaderData)
'MsgBox("Hello I'm reading ....")
If Me.DataTextBox.Text = "" Then
Me.DataTextBox.Text = TheReaderData.Text
' Here begins the verification of the length
If Len(Me.DataTextBox.Text) = Me.TextBox6.Text Then
' The length is ok
objStreamWriter.WriteLine(Me.DataTextBox.Text)
'Update the last read
Me.Label5.Text = Me.DataTextBox.Text
'Clean the field of the current read
Me.DataTextBox.Text = ""
'The counter of the code bars reads increases +1
Me.TextBox3.Text = Me.TextBox3.Text + 1
Else
Me.DataTextBox.Text = ""
MessageBox.Show("The length of the string read is not as expected", "Error !")
End If
End If
End Sub
The problem begins when I read a barcode with a length different to Me.TextBox6.Text (24 for example), the messagebox is shows ok, but inmediatelly another message box appear with the next error:
"StartRead Invalid Request Read already pending"
and the program continues fine, I need to eliminate this error because looks very bad.
Any help ?
Thanks in advance.
MessageBox does not stop your application from processing other events and it may be that a new barcode is read (or the same barcode is notified again) while you are still in the function processing the previous one.
Did you try to remove the call to MessageBox and check if this is still happening?
You may need to disable the reader before you call MessageBox.
I'm not even sure I understand this situation enough to come up with a proper title. I come from a modest understanding of VB6 and having to climb a steep learning curve for VB 2010.
I am trying to create a multi-client server program that will communicate with my Enterprise iPhone app. I found a relatively simple example to build upon here: http://www.strokenine.com/blog/?p=218. I have been able to modify the code enough to make it work with my app, but with one glitch: I can't get access to the controls on the form to add items, even though the method is invoked within the form's class. (I tried this on the original code too, and it does the same thing. I don't know how the author managed to get it to work.)
Here's the code segment in question:
Public Class Server 'The form with the controls is on/in this class.
Dim clients As New Hashtable 'new database (hashtable) to hold the clients
Sub recieved(ByVal msg As String, ByVal client As ConnectedClient)
Dim message() As String = msg.Split("|") 'make an array with elements of the message recieved
Select Case message(0) 'process by the first element in the array
Case "CHAT" 'if it's CHAT
TextBox3.Text &= client.name & " says: " & " " & message(1) & vbNewLine 'add the message to the chatbox
sendallbutone(message(1), client.name) 'this will update all clients with the new message
' and it will not send the message to the client it recieved it from :)
Case "LOGIN" 'A client has connected
clients.Add(client, client.name) 'add the client to our database (a hashtable)
ListBox1.Items.Add(client.name) 'add the client to the listbox to display the new user
End Select
End Sub
Under Case "LOGIN" the code tries to add the login ID to the listbox. It throws an exception: "A first chance exception of type 'System.InvalidOperationException' occurred in System.Windows.Forms.dll" The listbox (all controls, for that matter) is in the same class, Server.vb and Server.vb [Design].
The data comes in from another class that is created whenever a client logs on, which raises the event that switches back to the Server class:
Public Class ConnectedClient
Public Event gotmessage(ByVal message As String, ByVal client As ConnectedClient) 'this is raised when we get a message from the client
Public Event disconnected(ByVal client As ConnectedClient) 'this is raised when we get the client disconnects
Sub read(ByVal ar As IAsyncResult) 'this will process all messages being recieved
Try
Dim sr As New StreamReader(cli.GetStream) 'initialize a new streamreader which will read from the client's stream
Dim msg As String = sr.ReadLine() 'create a new variable which will be used to hold the message being read
RaiseEvent gotmessage(msg, Me) 'tell the server a message has been recieved. Me is passed as an argument which represents
' the current client which it has recieved the message from to perform any client specific
' tasks if needed
cli.GetStream.BeginRead(New Byte() {0}, 0, 0, AddressOf read, Nothing) 'continue reading from the stream
Catch ex As Exception
Try 'if an error occurs in the reading purpose, we will try to read again to see if we still can read
Dim sr As New StreamReader(cli.GetStream) 'initialize a new streamreader which will read from the client's stream
Dim msg As String = sr.ReadLine() 'create a new variable which will be used to hold the message being read
RaiseEvent gotmessage(msg, Me) 'tell the server a message has been recieved. Me is passed as an argument which represents
' the current client which it has recieved the message from to perform any client specific
' tasks if needed
cli.GetStream.BeginRead(New Byte() {0}, 0, 0, AddressOf read, Nothing) 'continue reading from the stream
Catch ' IF WE STILL CANNOT READ
RaiseEvent disconnected(Me) 'WE CAN ASSUME THE CLIENT HAS DISCONNECTED
End Try
End Try
End Sub
I hope I am making sense with all this. It all seems to bounce back and forth, it seems so convoluted.
I've tried using Me.listbox1 and Server.listbox1 and several other similar structures, but to no avail.
I'm reading a lot about Invoke and Delegates, but would that be necessary if the method and the control are in the same class? Or do I have a fundamental misperception of what a class is?
Many thanks for any help I can get.
Private Delegate Sub UpdateListDelegate(byval itemName as string)
Private Sub UpdateList(byval itemName as string)
If Me.InvokeRequired Then
Me.Invoke(New UpdateListDelegate(AddressOf UpdateList), itemName)
Else
' UpdateList
' add list add code
ListBox1.Items.Add(itemName)
End If
End Sub
Add above, then replace:
ListBox1.Items.Add(client.name)
to
UpdateList(client.name)
Does it work? check the syntax, may have typo as I type it.
I have an application was working fine and all the email functionality was working fine.
From yesterday, I started getting below error
Error Message:Service not available, closing transmission channel. The server response was: 4.3.2 Service not available, closing transmission channel
My VB.net code for sendmail is given below:
Public Sub SendMessage(ByVal toAddress As String, ByVal ccAddress As String)
Try
Dim message As New MailMessage()
Dim client As New SmtpClient()
'Set the sender's address
message.From = New MailAddress(fromAddress)
If (toAddress.Trim.Length > 0) Then
For Each addr As String In toAddress.Split(";"c)
message.To.Add(New MailAddress(addr))
Next
End If
If (ccAddress.Trim.Length > 0) Then
For Each addr As String In ccAddress.Split(";"c)
message.CC.Add(New MailAddress(addr))
Next
End If
message.BodyEncoding = Encoding.UTF8
message.Subject = Subject
message.Body = Body
message.IsBodyHtml = True
client.Send(message)
Catch ex As Exception
ErrorHandler.WriteError(ex.Message)
End Try
End Sub
Please suggest what can be cause behind this error and do let me know how can I fix this issue.
There isn't anything wrong with your code. This part of the error message:
4.3.2 Service not available, closing transmission channel
Is actually coming from your mail server, and the framework is simply passing the error message on to your application, and throwing it as part of the exception.
4.x.x errors are usually temporary, and are meant to be retried. Typically mail servers are overloaded when they throw a 400 error.
Check your email and see if it starts working.
Instead of (or in addition to) smtp authentication, some email servers will allow mail to be sent for 30 minutes (or some length) after a client computer checks POP email. If this is the case, it can make an application that does not use smtp authentication appear work sometimes and not work sometimes, with no change in the code.