vb6 - readfile hang on read serial port? - vb6

i use readfile to read data from serial port by api instead of WinComm. it works okay but hang on data receive when other side does not sent data, here are some codes:
'----------on port connect section---------------
With cTimeOuts
.ReadIntervalTimeout = 20
.ReadTotalTimeoutMultiplier = 20
.ReadTotalTimeoutConstant = 20
.WriteTotalTimeoutMultiplier = 20
.WriteTotalTimeoutConstant = 20
End With
rtLng = SetCommTimeouts(hPort, cTimeOuts)
'----------on data receive section---------------
With dOverlapped
.Internal = 0
.InternalHigh = 0
.offset = 0
.OffsetHigh = 0
.hEvent = 0
End With
call ReadFile(hPort, BytesBuffer(0), UBound(BytesBuffer) + 1, dwBytesRead, dOverlapped)
i tried:
a. set ReadIntervalTimeout to MAXDWORD and ReadTotalTimeoutMultiplier & ReadTotalTimeoutConstant both to 0, it can avoid hang on receive data, but the receive data will incomplete for random occurred, so this is not my option.
b. some example code on internet using
Call ReadFile(hPort, BytesBuffer(0), UBound(BytesBuffer) + 1, dwBytesRead, 0) using 0 instead of Overlapped setting, but the program crashed.
so i don't know using what to fix this, another thread? or Overlapped? some actual vb6 code is better cause i'm not familiar with this section, thank you!

Related

Errors in running Leach Protocol in Omnet++(Castalia )

I am running Leach protocol simulations in Castalia Omnet++ with the following simulation parameters:
sim-time-limit = 100s
SN.field_x = 70
SN.field_y = 70
SN.numNodes = 10
SN.deployment = "[1..9]->uniform"
SN.node[*].Communication.RoutingProtocolName = "LeachRouting"
SN.node[*].Communication.Routing.netBufferSize = 1000
SN.node[0].Communication.Routing.isSink = true
SN.node[*].Communication.Routing.slotLength = 0.2
SN.node[*].Communication.Routing.roundLength = 20s
SN.node[*].Communication.Routing.percentage = 0.05
SN.node[*].Communication.Routing.powersConfig = xmldoc("powersConfig.xml")
SN.node[*].ApplicationName = "ThroughputTest"
SN.node[*].Application.packet_rate = 1
SN.node[*].Application.constantDataPayload = 200
After running simulations, I checked the Castalia trace file and found the following errors:
SN.node[1].Communication.Radio Failed packet (WC_SIGNAL_START) from
node 6, radio not in RX state
SN.node[1].Communication.Radio Failed packet (WC_SIGNAL_END) from node
6, NO interference
Are these errors occurs due to simulation parameters or is there any other reason?
The messages you see are not errors per se. It could be normal behaviour. The messages just tell you that when a packet from node 6 arrived at node 1, node 1 did not have its radio in RX mode (listening) so it could not receive the packet.
This is a problem only when you lose most of your info-carrying packets, or you do not have a way to recover from such losses. You do not provide information whether this is the case or not.
The MAC plays a crucial role in this. The MAC puts the radio in RX or TX or Sleep mode. In the list of simulation parameters, the MAC is absent. If we assume that you use the default value, then this is bypassMAC that does not put the Radio to Sleep mode. Only way to have this message appear is for node 1 to TX at the same time it receives the packet from node 6.
These are normal messages, not errors. You can check Radio.cc to know why these messages are generated and adjust your code.

Reading serial output from Pyserial doesnt work reliably

I am connecting to device using code blow on MacOS and out of 100 times this code would make connection only 1 or two times and dones't respond(since there is no timeout) rest of the times.
ser = serial.Serial(port="/dev/xyz",timeout = None, baudrate=115200, parity = serial.PARITY_NONE, bytesize = serial.EIGHTBITS, stopbits = serial.STOPBITS_ONE)
def exitSer(ser):
print("Closing")
ser.close()
atexit.register(exitSer, ser)
if ser.is_open:
time.sleep(2)
while(1):
print(ser.readline().decode("utf-8"))
Could you please tell me how to use programs like fcntl etc to find if this port is completely free and available for use and how to set tty port's flags to free after making port free forcibly.
Once this works, I have to run this multithreaded where each thread is running different devices expecting output in lines. Any suggestions for that just in case this works.
def startSerial(tty_id):
ser = serial.Serial(port = tty_id, timeout = None)
ser.close()
ser.open()
if ser.isOpen():
print(ser.portstr, ":connection successful.")
return ser
else:
return False
Calling ser.close() before .open() fixed it. I tested it about 200 times and i haven't been dissappointed so far. I am testing it now in multithreaded and hopefully that works too.
Thank you everybody.

Need with Help Invalid outside source error

I am trying to process information with a dead mans program. Every time I try to run it I get Compile error Invalid outside procedure. I've never messed with VB6 before. I've been searching for a solution but I only get help saying it needs to be in sub or something but the threads are closed and I haven't been able to get their solutions to work for me. http://pastebin.com/vR7A7iN5
I think the problem is in this specific section of the code but I am unsure how to place it into a sub or get it to work otherwise.
End Type
Dim recout As statrec
Open "\STAT\PP\QM1409\MGA013A\" For Random As #1 Len = 150
num.recs = LOF(1) / 150
Print num.recs
For Count = 1 To num.recs
Get #1, Count, recout
If recout.mga = "013" Then
It is a big reach to assume this is the only incompatibility, but start by wrapping the code you're talking about now inside a method as Plutonix mentioned. That IS definitely an error. However I would not be surprised if there are more problems.
Example:
Public Sub GetStatRecs()
Dim recout As statrec
Open "\STAT\PP\QM1409\MGA013A\" For Random As #1 Len = 150
num.recs = LOF(1) / 150
Print num.recs
For Count = 1 To num.recs
Get #1, Count, recout
....
Next Count
....
End Sub

Sending an object to a client computer after connection made

I have a program that currently works as a chat server. It's a turn based card game with a chat box to communicate with the opponent. The chat stuff all works over the connection, but I'm to the point where I need to start sending certain cards to the opponent, so that when I play a card, my opponent will see it on his screen. I want the client computer to receive the object or collection of objects, figure out what the card type is based on its properties, and then put the card in the correct location. The sending and receiving part is what I don't understand how to accomplish. From what I've read, this requires serialization and I just don't know where to begin with this. Please assist! I'm using visual studio.
Answering my own question again... I ended up creating a new class called card container which contains the cardType as a string and the card id as a int. There are also other properties for the card container so I know where the card goes. Then I serialized the card container (which is 'cc' in the following code) and sent it as follows:
Dim cc as new CardContainer
cc.id = card.id
cc.cardType = card.GetType.ToString
cc.discard = true
Dim bf As New BinaryFormatter
Dim ms As New MemoryStream
Dim b() As Byte
'serializes to the created memory stream
bf.Serialize(ms, cc)
'converts the memory stream to the byte array
b = ms.ToArray()
ms.Close()
'sends the byte array to client or host
SyncLock mobjClient.GetStream
mobjClient.GetStream.Write(b, 0, b.Length)
End SyncLock
The client listens on its TCPClient for anything at all and picks up the card with the following code:
Dim intCount As Integer
Try
SyncLock mobjClient.GetStream
'returns the number of bytes to know how many to read
intCount = mobjClient.GetStream.EndRead(ar)
End SyncLock
'if no bytes then we are disconnected
If intCount < 1 Then
MarkAsDisconnected()
Exit Sub
End If
Dim bf As New BinaryFormatter
Dim cc As New CardContainer
'moves the byte array found in arData to the memory stream
Dim ms As New MemoryStream(arData)
'cuts off the byte array in the memory stream after all the received data
ms.SetLength(intCount)
'the new cardContainer will now be just like the sent one
cc = bf.Deserialize(ms)
ms.Close()
'starts the listener again
mobjClient.GetStream.BeginRead(arData, 0, 3145728, AddressOf DoRead, Nothing)
Depending on what data the cardcontainer has determines which method the client now calls. For example, when this is received, the created cc is passed to my CardReceived method which then has a bunch of if, elseif statements. One of those would be
ElseIf cc.discard = true then
'makes a new card from the id and cardType properties
dim temp as new object = MakeCard
'discard method will find the correct card in the Host's known hand and discard it to the correct pile
Discard(temp)

Ruby TCPServer sockets

Maybe I've gotten my sockets programming way mixed up, but shouldn't something like this work?
srv = TCPServer.open(3333)
client = srv.accept
data = ""
while (tmp = client.recv(10))
data += tmp
end
I've tried pretty much every other method of "getting" data from the client TCPSocket, but all of them hang and never break out of the loop (getc, gets, read, etc). I feel like I'm forgetting something. What am I missing?
In order for the server to be well written you will need to either:
Know in advance the amount of data that will be communicated: In this case you can use the method read(size) instead of recv(size). read blocks until the total amount of bytes is received.
Have a termination sequence: In this case you keep a loop on recv until you receive a sequence of bytes indicating the communication is over.
Have the client closing the socket after finishing the communication: In this case read will return with partial data or with 0 and recv will return with 0 size data data.empty?==true.
Defining a communication timeout: You can use the function select in order to get a timeout when no communication was done after a certain period of time. In which case you will close the socket and assume every data was communicated.
Hope this helps.
Hmm, I keep doing this on stack overflow [answering my own questions]. Maybe it will help somebody else. I found an easier way to go about doing what I was trying to do:
srv = TCPServer.open(3333)
client = srv.accept
data = ""
recv_length = 56
while (tmp = client.recv(recv_length))
data += tmp
break if tmp.length < recv_length
end
There is nothing that can be written to the socket so that client.recv(10) returns nil or false.
Try:
srv = TCPServer.open(3333)
client = srv.accept
data = ""
while (tmp = client.recv(10) and tmp != 'QUIT')
data += tmp
end

Resources