I have a lot of GPS devices. One of my device (as client) send this message every minutes on TCP "[3G*4700201934*0009*LK,0,1,61]"
and my server have to read the message from GPS device and reply to device, I mean my server must send this message "[3G*4700201934*0009*LK]" for getting GPS positions. If I can't send this message, GPS device doesn't send the positions of GPS.
My code:
TcpListener listener = new TcpListener(IPAddress.Any, port);
listener.Start();
//Sonsuz döngü sayesinde AgAkimini sürekli okuyoruz
while (true)
{
Socket client = listener.AcceptSocket();
Console.WriteLine("Connection accepted.");
var childSocketThread = new Thread(() =>
{
byte[] data = new byte[100];
int size = client.Receive(data);
string fromGPSMessage = string.Empty;
for (int i = 0; i < size; i++)
fromGPSMessage += Convert.ToChar(data[i]);
Console.WriteLine("Recieved data: " + fromGPSMessage);
//fromGPSMessage = [3G*4700201934*0009*LK,0,1,59]
string serverMessageToGPS = fromGPSMessage.Substring(0, fromGPSMessage.IndexOf(",")) + "]";
//serverMessageToGPS = [3G*4700201934*0009*LK]
Encoding ascii = Encoding.ASCII;
client.Send(ascii.GetBytes(serverMessageToGPS));
data = new byte[100];
size = client.Receive(data);
string newMessagefromGPSMessage = string.Empty;
for (int i = 0; i < size; i++)
newMessagefromGPSMessage += Convert.ToChar(data[i]);
Console.WriteLine("New Message Data: " + newMessagefromGPSMessage);
client.Close();
});
childSocketThread.Start();
}
sometimes there is no new message data:
I can send message to device but I don't know how to get second message from GPS device.
You should create TCP OnReceive event. So when new data comes, OnReceive event executed and you can parse data.
In your code, you have written client.Receive(data), so it will receive data single time. To receive all data, you have to implement OnReceive event or you can put client.Receive(data) method in loop with threading.
It sounds like you need to read up on TcpClient: MSDN documentation
The example on that page shows you how to send data, and also how to read data returned to you.
Related
I am trying to develop a software (in C#) that collect some data on a list (List<string> socketList). The value of this list must be sent to a processing software.
In this program, the server (the C# software) waits for a message from a client (the Processing software) and send an element of the list. This list is continuously filled by a method in another thread (I verify, the list is everytime full). I used this method because I need that each value has to arrive at a client, no matter the speed.
Here there is the method in C# (it is launched as a thread):
public static void InizializeSocket()
{
//setting the comunication port
int port = 5000;
//infinite loop in order to accept sequential clients
while (true)
{
//I open the listener for any IP
TcpListener listener = new TcpListener(IPAddress.Any, port);
Console.WriteLine("Listening...");
//Waiting for a client
listener.Start();
TcpClient client = listener.AcceptTcpClient();
Console.WriteLine("CONNECTED");
//this string will contain the client message
String dataReceived = "";
//loop until "q". If the client send a message with a q, the server disconnect the client
while (dataReceived != "q")
{
//Read the client message
NetworkStream nwStream = client.GetStream();
try
{
//Define the client message buffer dimension and read the message
byte[] buffer = new byte[client.ReceiveBufferSize];
int bytesRead = nwStream.Read(buffer, 0, client.ReceiveBufferSize);
//Encoding the byte in a string
dataReceived = Encoding.ASCII.GetString(buffer, 0, bytesRead);
//check if the List<string> socketList is not empty. If it has any elements, I send the first one and after that I remove the element from the list
if (socketList.Count > 0)
{
//Encoding the string in a byte
byte[] bytesToSend = ASCIIEncoding.ASCII.GetBytes(socketList[0]);
nwStream.Write(bytesToSend, 0, bytesToSend.Length);
socketList.RemoveAt(0);
}
nwStream.Flush();
}
catch (Exception e) { dataReceived = "q"; }
}
//Exit from the client loop
Console.WriteLine("DISCONNECTED");
client.Close();
listener.Stop();
}
}
And here the simple Processing software
import processing.net.*;
Client myClient;
String dataIn;
int port = 5000;
String ip = "127.0.0.1";
void setup () {
size(1100, 1025);
//Initialize the client
myClient = new Client(this, "127.0.0.1", 5000);
}
void draw () {
//If the client is available it send a generic message to the server and try to receive a response
if (myClient.available() > 0) {
myClient.write("c");
dataIn = myClient.readString();
}
//print the output in debug
println(dataIn);
}
Here the Processing software is able to connect, anyway, I received every time null.
In addition, if I try to write (in the try on the C# software) only:
if (socketList.Count > 0)
{
byte[] bytesToSend = ASCIIEncoding.ASCII.GetBytes(socketList[0]);
nwStream.Write(bytesToSend, 0, bytesToSend.Length);
socketList.RemoveAt(0);
}
I receive strange values that are not the same values in the list stored in C# software.
So, why in the first case processing read only null value? And why in the second case it read "random" value?
EDIT:
Analyze better the programs flow, I verify where is the problem. I rewrite the processing socket as a java socket. It is launched in another thread and fills an ArrayList.
Considering a simplification of the code (in order to understand better), if I write:
Socket s = new Socket("localhost", 5000);
BufferedReader input =new BufferedReader(new InputStreamReader(s.getInputStream()));
PrintWriter out= new PrintWriter(s.getOutputStream(), true);
out.println("hello");
String temp = input.readLine();
the software blocks on String temp = input.readLine();. Anyway, the communication is established and I am sure that C# send the string.
I have this simple tcp server class
class Server
{
private TcpListener tcpListener;
private Thread listenThread;
public Server()
{
this.tcpListener = new TcpListener(IPAddress.Parse("127.0.0.1"), 3000);
this.listenThread = new Thread(new ThreadStart(ListenForClients));
this.listenThread.Start();
Console.WriteLine("Hello");
}
private void ListenForClients()
{
this.tcpListener.Start();
while (true)
{
//blocks until a client has connected to the server
TcpClient client = this.tcpListener.AcceptTcpClient();
//create a thread to handle communication
//with connected client
Thread clientThread = new Thread(new ParameterizedThreadStart(HandleClientComm));
Console.WriteLine("New connexion");
clientThread.Start(client);
}
}
private void HandleClientComm(object client)
{
TcpClient tcpClient = (TcpClient)client;
NetworkStream clientStream = tcpClient.GetStream();
Console.WriteLine("Got Stream");
byte[] message = new byte[4096];
int bytesRead;
Console.WriteLine("Initializing..");
while (true)
{
bytesRead = 0;
try
{
//blocks until a client sends a message
Console.WriteLine("Reading..");
bytesRead = clientStream.Read(message, 0, 4096);
Console.WriteLine("Received something");
}
catch
{
//a socket error has occured
break;
}
if (bytesRead == 0)
{
//the client has disconnected from the server
break;
}
//message has successfully been received
ASCIIEncoding encoder = new ASCIIEncoding();
Console.WriteLine(encoder.GetString(message, 0, bytesRead));
}
tcpClient.Close();
}
}
I simply call it in the main function like this :
Server server = new Server();
And in a separate client program I have this class
class TheClient
{
public void ConnectV2()
{
TcpClient client = new TcpClient();
IPEndPoint serverEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 3000);
client.Connect(serverEndPoint);
NetworkStream clientStream = client.GetStream();
ASCIIEncoding encoder = new ASCIIEncoding();
for (int i = 0; i < 20; i++)
{
byte[] buffer = encoder.GetBytes("Hello Server! " + i.ToString() + " ");
Console.WriteLine("Processing..");
clientStream.Write(buffer, 0, buffer.Length);
clientStream.Flush();
Console.WriteLine("Hello Server sent");
}
}
}
I call it in the main function like
TheClient tc = new TheClient();
tc.ConnectV2();
My problem is that the server program seems slower than the client, he don't react before the 13th, or more, message from the client :
[I can't post images because of reputation]
It reads the first dozen of messages in one go, and then reads the others one by one.
And if I make the server emit first, the client receive the message, but they both stop, like if both wait for the other to send something.
Can someone explain me this behavior ? How can I control and synchronize it ?
TCP is not message based. It provides a stream of bytes. It is your responsibility to separate messages. Also note, that you might receive only a part of a message in one Read call.
Here's a simple way to do that: Send the messages as individual lines. Possibly using StreamWriter. Receive the messages using StreamReader.ReadLine().
That way you can also use a more sane encoding such as Encoding.UTF8.
Besides that your code is actually fine and workable. It is extremely rare to see almost working TCP code on Stack Overflow. Most code is horribly broken. Congratulations.
It's because that your client AP is always sending data ,but your server AP cannot receive those data right away. So,those data stacked in buffer and then server AP receive all at once.
You can try:
Set fixed lengths when you send or receive data.
or
Receive and split data.
I'm trying to implement ping based on udp packets with C#. The idea is to send udp packets to wrong port and get back ICMP packets contating Port unreachable error. And the time elapsed between seding the udp packet and recieveing the icmp packet is a ping time. I do it like that:
// Start building the headers
//Console.WriteLine("Building the packet header...");
int messageSize = 64;
byte[] builtPacket, payLoad = new byte[messageSize];
UdpHeader udpPacket = new UdpHeader();
ArrayList headerList = new ArrayList();
Socket rawSocket = null;
SocketOptionLevel socketLevel;
// Initialize the payload
//Console.WriteLine("Initialize the payload...");
for (int i = 0; i < payLoad.Length; i++)
payLoad[i] = (byte)'0';
// Fill out the UDP header first
//Console.WriteLine("Filling out the UDP header...");
udpPacket.SourcePort = 33434;
udpPacket.DestinationPort = 33434;
udpPacket.Length = (ushort)(UdpHeader.UdpHeaderLength + messageSize);
udpPacket.Checksum = 0;
Ipv4Header ipv4Packet = new Ipv4Header();
// Build the IPv4 header
//Console.WriteLine("Building the IPv4 header...");
ipv4Packet.Version = 4;
ipv4Packet.Protocol = (byte)ProtocolType.Udp;
ipv4Packet.Ttl = 30;
ipv4Packet.Offset = 0;
ipv4Packet.Length = (byte)Ipv4Header.Ipv4HeaderLength;
ipv4Packet.TotalLength = (ushort)Convert.ToUInt16(Ipv4Header.Ipv4HeaderLength + UdpHeader.UdpHeaderLength + messageSize);
ipv4Packet.SourceAddress = sourceAddress;
ipv4Packet.DestinationAddress = destAddress;
// Set the IPv4 header in the UDP header since it is required to calculate the
// pseudo header checksum
//Console.WriteLine("Setting the IPv4 header for pseudo header checksum...");
udpPacket.ipv4PacketHeader = ipv4Packet;
// Add IPv4 header to list of headers -- headers should be added in th order
// they appear in the packet (i.e. IP first then UDP)
//Console.WriteLine("Adding the IPv4 header to the list of header, encapsulating packet...");
headerList.Add(ipv4Packet);
socketLevel = SocketOptionLevel.IP;
// Add the UDP header to list of headers after the IP header has been added
//Console.WriteLine("Adding the UDP header to the list of header, after IP header...");
headerList.Add(udpPacket);
// Convert the header classes into the binary on-the-wire representation
//Console.WriteLine("Converting the header classes into the binary...");
builtPacket = udpPacket.BuildPacket(headerList, payLoad);
// Create the raw socket for this packet
//Console.WriteLine("Creating the raw socket using Socket()...");
rawSocket = new Socket(sourceAddress.AddressFamily, SocketType.Raw, ProtocolType.Udp);
// Bind the socket to the interface specified
//Console.WriteLine("Binding the socket to the specified interface using Bind()...");
IPAddress bindAddress = IPAddress.Any;
rawSocket.Bind(new IPEndPoint(bindAddress, 0));
// Set the HeaderIncluded option since we include the IP header
//Console.WriteLine("Setting the HeaderIncluded option for IP header...");
rawSocket.SetSocketOption(socketLevel, SocketOptionName.HeaderIncluded, 1);
rawSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 1000);
Stopwatch timer = new Stopwatch();
try {
for (int i = 0; i < 5; i++) {
timer.Reset();
timer.Start();
int rc = rawSocket.SendTo(builtPacket, new IPEndPoint(destAddress, 0));
Console.WriteLine("Sent {0} bytes to {1}", rc, destAddress);
Socket icmpListener = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.Icmp);
icmpListener.Bind(new IPEndPoint(sourceAddress, 0));
icmpListener.IOControl(IOControlCode.ReceiveAll, new byte[] { 1, 0, 0, 0 }, new byte[] { 1, 0, 0, 0 });
icmpListener.Shutdown(SocketShutdown.Send);
byte[] buffer = new byte[4096];
EndPoint remoteEndPoint = new IPEndPoint(IPAddress.Any, 0);
try {
int bytesRead = icmpListener.ReceiveFrom(buffer, ref remoteEndPoint);
timer.Stop();
Console.WriteLine("Recieved " + bytesRead + " bytes from " + destAddress + " in " + timer.ElapsedMilliseconds + "ms\n");
}
catch {
Console.WriteLine("Server is not responding!");
}
finally {
icmpListener.Close();
}
}
}
catch (SocketException err) {
Console.WriteLine("Socket error occurred: {0}", err.Message);
}
finally {
rawSocket.Close();
}
And it works from time to time. The thing is that some web-sites send me an icmp packet and some not. Actually at first they also were not sending then I used Windows ping to ping them and tracert to traceroute them. And changed port number and it worked. But not for all. I can ping only google.com and one more site but others don't send icmp packet back. The same situation with local network computers I tried to ping. I send udp packet and don't get icmp back.
I used wireshark to watch packets flying.
What am I doing wrong in here?
I am a Newbie to TCP/IP programming in c#, so I am DESPERATE for a solution to my current problem!
I have designed a C# Windows application running under Windows 7 with a Sqlserver 2005 database. My application is trying to send an HL7 record over a TCP/IP connection, to a Unix Lab. system machine.
I can get a connection ok, and send the HL7. BUT I cannot get ANY reply from the Lab. server! the connection times-out with error code 10060, as well as a _COMPlusExceptionCode value of -532462766.
Here is a sample of my c# 'Connect' methods:
buildSendHL7_TCPIP hl7Agent = new buildSendHL7_TCPIP();
// class 'buildSendHL7_TCPIP(); ' contains methods to build the HL7 segments, as well as methods to send and receive messages over the TCP connection
string strServerIPAddress = string.Empty;
Int32 intSocketNo = new Int32();
bool sentOK = false;
/***********************************/
/*Try send the HL7 to LIS-HORIZON...*/
/***********************************/
strServerIPAddress = "10.1.6.248";
intSocketNo = 5910;
sentOK = hl7Agent.SendHL7(strServerIPAddress, intSocketNo, strHL7_Record);
if (!sentOK)
{
_strUIMessage = "*Error* HL7 Message NOT sent to LIS!";
opsMessageBox mb = new opsMessageBox(this);
mb.ShowDialog();
mb.Close();
goto EndLabel;
}
Here are the methods I've created to build a TCP connection and send the HL7 to the LIS Server:
public bool SendHL7(string strIPAddress, Int32 intSocket, string hl7message)
{
/* send the complete HL7 message to the server...*/
int port = (int)intSocket;
IPAddress localAddr = IPAddress.Parse(strIPAddress);
try
{
// Add the leading & trailing character field-separator and CR LineFeed' t.
string llphl7message = null;
llphl7message = "|";
llphl7message += hl7message;
llphl7message += Convert.ToChar(28).ToString();
llphl7message += Convert.ToChar(13).ToString();
// Get the size of the message that we have to send.
Byte[] bytesToSend = Encoding.ASCII.GetBytes(llphl7message);
Byte[] bytesReceived = new Byte[256];
// Create a socket connection with the specified server and port.
Socket s = ConnectSocket(localAddr, port);
// If the socket could not get a connection, then return false.
if (s == null)
return false;
// Send message to the server.
s.Send(bytesToSend, bytesToSend.Length, 0);
// Receive the response back
int bytes = 0;
s.ReceiveTimeout = 3000; /* 3 seconds wait before timeout */
bytes = s.Receive(bytesReceived, bytesReceived.Length, 0); /* IMEOUT occurs!!! */
string page = Encoding.ASCII.GetString(bytesReceived, 0, bytes);
s.Close();
// Check to see if it was successful
if (page.Contains("MSA|AA"))
{
return true;
}
else
{
return false;
}
}
catch (SocketException e)
{
MessageBox.Show("SocketExecptionError:" + e);
return false;
}
}
private static Socket ConnectSocket(IPAddress server, int port)
{
Socket s = null;
IPHostEntry hostEntry = null;
// Get host related information.
hostEntry = Dns.GetHostEntry(server);
foreach (IPAddress address in hostEntry.AddressList)
{
IPEndPoint ipe = new IPEndPoint(address, port);
Socket tempSocket = new Socket(ipe.AddressFamily,SocketType.Stream,ProtocolType.Tcp);
tempSocket.Connect(ipe);
if (tempSocket.Connected)
{
s = tempSocket;
break;
}
else
{
continue;
}
}
return s;
}
I've been told that socket 5910 cannot receive ANY communications in Windows 7 due to Virus issues. Is this true? If so, I tried to connect to ANOTHER server on our network (PACS/RIS) socket # 5556. I get the SAME timeout error message.
The behaviour looks like the server doesn't understand your request / doesn't recognize it as a complete message according to the expected protocol.
As I understand from your code you are sending a HL7 message. I don't know this protocol, according to google it could be Health Level 7. The example I found is starting with some text, then a | as a delimiter. Your message is starting with |. Maybe there is the problem...
So you should have a look if the message you send is matching the protocol definition.
When i send data through TCP server to client first time full name retrieved when i again send the another name like book it retrieved as (ook) in C sharp
client side code
sck = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
while (true)
{
IPEndPoint localEndPoint;
localEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.2"), 1);
try
{
sck.Connect(localEndPoint);
}
catch
{
Console.Write("Unable to connect to remote end point!\r\n");
);
}
Console.Write("Enter Text: ");
string text = Console.ReadLine();
byte[] data = Encoding.ASCII.GetBytes(text);
sck.Send(data);
Console.Write("Data Sent!\r\n");
sck.Close();
Console.ReadLine();
Server Side Code
while (true)
{
Socket accepted = sck.Accept();
Buffer = new byte[accepted.SendBufferSize];
int bytesRead = accepted.Receive(Buffer);
byte[] formatted = new byte[bytesRead];
for (int i = 0; i < bytesRead; i++)
{
formatted[i] = Buffer[i];
//Console.WriteLine(Buffer[i] + "\r\n");
}
//string strData = Encoding.ASCII.GetString(Buffer);
string strData = Encoding.ASCII.GetString(formatted);
Console.Write(strData + "\r\n");
accepted.Close();
}
There is something which I don't understand, you use Buffer as a variable but that is a type in C#, I don't know where and how you declare it.
Anyway, I would do it like this:
while (true)
{
Socket accepted = sck.Accept();
byte[] buffer = new byte[1024];
int ret=0;
StringBuilder sb= new StringBuilder();
while ((ret=accepted.Receive(buffer)) > 0)
{
sb.Append(Encoding.ASCII.GetString(buffer, 0, ret));
}
Console.Write(sb.ToString() + "\r\n");
accepted.Close();
}
In order to keep a dialog between both sockets you need something called a protocol, which means you know when you have received the whole data then you reply to the sender. A protocol could be: send a packet which inform what you are going to send, length of the message mainly. Other way is to stop reading when something comes into the message, for example the string "#END#" the return character '\r', etc. If you only want to send one single message and received back a reply message one thing you can do, however, is to shutdown the client part, only the send part Socket.Shutdown(SocketShutdown.Send);, with that, the sender tells the receiver it has sent all data, the receiver receives that signal and then it can send a reply message to the sender.
The client:
sck.Send(data);
Console.Write("Data Sent!\r\n");
// tell the server we have done sending data.
sck.Shutdown(SocketShutdown.Send);
// Now receive from the server
byte[] buffer = new byte[1024];
int ret = 0;
StringBuilder sb = new StringBuilder();
while ((ret = sck.Receive(buffer)) > 0)
{
sb.Append(Encoding.ASCII.GetString(buffer, 0, ret));
}
Console.Write(sb.ToString() + "\r\n");
sck.Close();
The server
while (true)
{
Socket accepted = sck.Accept();
byte[] buffer = new byte[1024];
int ret=0;
StringBuilder sb= new StringBuilder();
while ((ret=accepted.Receive(buffer)) > 0)
{
sb.Append(Encoding.ASCII.GetString(buffer, 0, ret));
}
Console.Write(sb.ToString() + "\r\n");
byte[] reply = Encoding.ASCII.GetBytes("I've got it!");
accepted.Send(reply);
accepted.Close();
}