I have 2 devices communicating throw a serial port, i ordered a "T" shaped serial port cable and can listen to the transaction between my 2 devices, when i try with a monitoring soft i have no problem to get ALL the data but when i try whith c# code i only get 1st line right and then i miss char and get "?" instead of some data. Here is more or less what i had on serialport datarecievedhandler:
private void DataReceviedHandler(object sender,SerialDataReceivedEventArgs
e)
{
SerialPort sp = (SerialPort)sender;
this.Data = sp.ReadExisting();
}
giving me line like : CRC ???ogram?? DA?E
I found topic where they talked about Multithreading to be able to continuously listen to port whithout having to stop to listen when "getting" data but this notion is new to me and i don't know how to inplement it.
Isn't there a way to recieve data until a timeout on a "Nodatasend" to then get my data and re-listen to my port ?
Related
I am working on making GUI for a Smart Water flow meter whose communication protocol is RS485,
as per instructions from Communication Manual i am sending an inquiry packet and i am receiving proper response in serial port terminal. But when i am trying to do it on my C# app.
Things are happening oppositely.
string data = "[H201815000081]";
private void button1_Click(object sender, EventArgs e)
{
serialPort1.Write(data);
incoming_data = serialPort1.ReadExisting();
text_reciever.Text = incoming_data;
}
// text_reciver is the text box of my gui where i want to display the
// values from flow meter.Data Type of incoming_data is string
Here is the code, i am sending an inquiry code to the device and in return i am getting garbage values on my text box. Some times it is stream of Question mark symbol (?), some time it shows nothing.
But when i revert myself to serial port terminal (Real Term).
It is showing proper values as mentioned in communication manual.
Please assist in this regards.
After looking around i just found the answer to my question.
The point is previously i was communicating with serial port teminal, where everything was working fine, but when it comes to interacting with peripherals one need to make sure that Serialport.DTRProperty is enabled.
When opening the serial port one must enable the DTR property by:
serialPort1.DtrEnable = true;
Otherwise the windows form will read the garbage value.
the incoming data would be serial number of device (ASCII Format) and Water flow values
I try connect to scale via rs232 cable. When I try write "ENQ" to port then scale turn off and receive nothing. This is my code. Sorry my bad English :(
class ScaleCAS
{
private SerialPort port = new SerialPort("COM4", 9600, Parity.None, 8, StopBits.One);
public string result = null;
public ScaleCAS()
{
port.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);
port.Open();
}
private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
this.result = port.ReadExisting();
}
}
ADD
In another class I try write into port
Scale.port.write("ENQ");
Console.Write(Scale.result);
You are not waiting for your scale to answer, you read the value of result a way lot faster then it get filled with data.
A good way to communicate using SerialPort is with ReadLine and WriteLine, check out that NewLine was set correctly according to you device programming manual (which would be nice to add to the question if you are asking question about specific device).
Some general troubleshooting of RS232 communications:
Check baud rate and all other serial port configuration
Check what is the EOL (End of Line) character, and use it to terminate writing statements and to know how to stop reading input messages (or use ReadLine and WriteLine)
Check the communication manually using TeraTerm or some other serial terminal
This isn't a problem as much as it is a curiosity. I created a simple send/receive C# application using UDP, mostly following the MSDN examples on UdpClient. I have a textbox acting as a log for when things are sent or received; it prints the timestamp and what was sent/received from where.
The curiosity comes in with the port numbers. When the program is listening on some port and it receives a packet, the port on the packet received doesn't match up with the port it was listening on.
For example, here's a screenshot of the application (note: this still happens even if using different computers to send/receive):
It's receiving the packets just fine, which is why this isn't really a "problem" because it is working. I'm just curious why the port on the received packets is showing different than the port it is listening on. I'm wondering if perhaps it's just garbage data?
Here's the code that runs when data is received (using the AsyncCallback that I picked up from MSDN):
private void ReceiveCallback(IAsyncResult ar)
{
try {
// Pull the socket from the AsyncResult parameter
UdpState state = (UdpState)(ar.AsyncState);
UdpClient udp = state.udp;
IPEndPoint end = state.endpoint;
// Grab and convert the message into a string
byte[] recvBytes = udp.EndReceive(ar, ref end);
string recvString = Encoding.ASCII.GetString(recvBytes);
/* Here's where it's logging the IPEndPoint onto the console.
* Is the port meaningless when receiving a packet, and that's why it's
* always something random? Or is there some meaning to it that I'm
* unaware of? */
ConsoleLog(end.ToString() + " Recv: " + recvString);
// Start the listen cycle again so this will be called again
listener.BeginReceive(new AsyncCallback(ReceiveCallback), state);
} catch (ObjectDisposedException) {
// Do nothing - Expected error when the UDP Listener is closed.
}
}
Is the port number when receiving packets just meaningless garbage data, or does it have some sort of use?
Every UDP packet has a source and destination ip address and port, what you are seeing is the source port address.
A well known port is used to send data to, the machine sending data assigns a free port to the source port of the packet so that it can receive data from the server on that port.
There's a port number at each end of the connection: the published port number that your process is listening on, and the originating (client) port number (which could be on a different machine).
Hi I am using TCPCLient and TCPlitner to transmit data but i am getting error not to connect
below is my Code
private void button1_Click(object sender, EventArgs e)
{
TcpClient tcpc = new TcpClient("192.168.21.46", 10);
NetworkStream nts = tcpc.GetStream();
if (nts.CanWrite)
{
Byte[] sends = System.Text.Encoding.ASCII.GetBytes(textBox1.Text.ToCharArray());
nts.Write(sends, 0, sends.Length);
nts.Flush();
}
}
private void button2_Click(object sender, EventArgs e)
{
TcpListener myListener = new TcpListener(10);
myListener.Start();
while (true)
{
//Accept a new connection
Socket mySocket = myListener.AcceptSocket();
if (mySocket.Connected)
{
//make a byte array and receive data from the client
Byte[] receive = new Byte[64];
int i = mySocket.Receive(receive, receive.Length, 0);
char[] unwanted = { ' ', ' ', ' ' };
string rece = System.Text.Encoding.ASCII.GetString(receive);
label1.Text = rece.TrimEnd(unwanted);
}
}
}
this two buttons i have added in the same form and Ip apddress which is mentioned is my systems IP Address. Can anyone tell me why this Happen. Even I remove firewall setting also.
First of all your UI will hang on button 2 click because it's stuck on the while(true) loop so use BeginAcceptSocket(IAsyncResult r, Object state) for async.
Second you must use the loopback address or otherwise the firewall should block the port 10 assuming that it's not open. Also the TcpListener(int port) is obsolote and its better to use the TcpListener(IPAddress localddr, int port) and use both the loopback address.
I'm assuming you have two different programs and one is listening while the other is sending. If you don't, separate them out. I'm thinking you have a networking issue but can't say precisely why it's blocked.
You're using port 10, which generally is too low for arbitrary application uses even if it's not currently occupied. If you're building a custom protocol, try to listen on a port above approximately 1000 (more a rule of thumb). You can look here http://technet.microsoft.com/en-us/library/cc959828.aspx or google for "tcp well known ports" for more details and to ensure you don't have a collision.
Try running your TCP listener, then open a command prompt and typing the following
telnet localhost 10
or use the port number you change 10 to. I tried your code and was able to connect to port 10 without issue. If you don't have the "telnet" program you can turn the feature on in your Windows. (search "feature" and choose "turn windows feature on or off" then turn "Telnet Client" on)
If the telnet program connects, you'll know that the issue isn't connectivity related. If the telnet program fails to connect then you'll know something is still blocking that port. Try a different port and re-test connectivity. Once telnet connects, you can then focus on the TCP client portion of your program.
I am making an Win RT app that connects to a desktop app and they start to communicate in UDP and TCP.
I have successfully implemented TCP communication in that I can send from Win RT to Desktop and send from Desktop to Win RT. using StreamSocket on Win RT and TcpListener on desktop.
I also made it to send Udp data from Win RT to desktop without any problem. But I can't receive data's sent from desktop to Win RT. I use the following code and I don't see any problem with that but there must something.
var g = new DatagramSocket();
g.MessageReceived += g_MessageReceived;
g.BindEndpointAsync(new HostName("127.0.0.1"), "6700");
.
.
.
void g_MessageReceived(DatagramSocket sender, DatagramSocketMessageReceivedEventArgs args)
{ // <- break point here.
}
That break point never stops the code which means it never gets a message.
I can only think of IBuffer because on my StreamSocket I should get the bytes by reader.GetBuffers() and not reader.GetBytes(). However that's the thing I need to think about on the Win RT and not Desktop. because on Tcp I just send bytes and I get buffers in Win RT so the same should happen for DatagramSocket as well.
reader = DataReader
Thank you guys.
I'm not familiar with the new DatagramSocket class, but usually binding to 127.0.0.1 means that you will only receive messages sent to the loopback adapter. Since your packets are coming from another host, they should be received on a NIC, not the loopback adapter.
Edit: From looking at the documentation for the DatagramSocket API that you're using, you can just use the BindServiceNameAsync() method instead of BindEndpointAsync() in order to bind to the specified port on all adapters, which is the same behavior as my System.Net.Sockets API example below. So, in your example, you'd have:
g.BindServiceNameAsync("6700");
Of course, you'll also want to make sure your firewall settings on the desktop host allow it to listen for incoming UDP packets on the specified port.
Try the following code:
using System.Net;
using System.Net.Sockets;
public class UdpState
{
public UdpClient client;
public IPEndPoint ep;
}
...
private void btnStartListener_Click(object sender, EventArgs e)
{
UdpState state = new UdpState();
//This specifies that the UdpClient should listen on EVERY adapter
//on the specified port, not just on one adapter.
state.ep = new IPEndPoint(IPAddress.Any, 31337);
//This will call bind() using the above IP endpoint information.
state.client = new UdpClient(state.ep);
//This starts waiting for an incoming datagram and returns immediately.
state.client.BeginReceive(new AsyncCallback(bytesReceived), state);
}
private void bytesReceived(IAsyncResult async)
{
UdpState state = async.AsyncState as UdpState;
if (state != null)
{
IPEndPoint ep = state.ep;
string msg = ASCIIEncoding.ASCII.GetString(state.client.EndReceive(async, ref ep));
//either close the client or call BeginReceive to wait for next datagram here.
}
}
Note that in the above code, you should obviously use whatever encoding you're sending the string across with. When I wrote that test app, I sent the string in ASCII. If you're sending it in Unicode, just use UnicodeEncoding.Unicode instead of ASCIIEncoding.ASCII.
If none of this works, you might want to break out a packet capture utility like Wireshark to make sure that the UDP packet from the RT host is, in fact, getting to the desktop host.