Tcp Client is not sending second response packet - c#

I am working on a tracking device and it is working perfectly when it sends the packet and the server acknowledge it but there is a case when the device needs two acknowledgements against one packet.
I am sending both of two but I don't know why the device is not accepting it because after that the device is sending the login packet.
Note: Login packet is the packet which is sent by the device at the beginning of the connection and also when the device does not receive the desired acknowledgement.Can somebody help me in this matter?
Here is the server side code.
public async Task ParseAvlDataAsync(TcpClient client, NetworkStream stream , byte[] array)
{
var resp = Utils.GetInformationContent(array);
if (resp.Item2)
{
string imei = Utils.BytesToString(resp.Item1);
Console.WriteLine("IMEI received: " + imei);
Console.WriteLine("--------------------------------------------");
var response = Utils.CreateResponse(array);
await stream.WriteAsync(response, 0, response.Length).ConfigureAwait(false);
Console.WriteLine("Login response sent");
while (client.Connected)
{
stream = client.GetStream();
byte[] buffer = new byte[client.ReceiveBufferSize];
await stream.ReadAsync(buffer, 0, buffer.Length).ConfigureAwait(false);
//it can be Location data, status info, alarm data
//if it is location data then response will not be sent to the server
Console.WriteLine(string.Format("Get {0} Packet", (PROTOCOL_NUMBER)buffer[3]));
if ((PROTOCOL_NUMBER)buffer[3] != PROTOCOL_NUMBER.LOCATION_DATA && (PROTOCOL_NUMBER)buffer[3] != PROTOCOL_NUMBER.STRING_INFO)
{
if (Utils.IsVaidProtocol((PROTOCOL_NUMBER)buffer[3]))
{
//send first response for every packet
response = Utils.CreateResponse(buffer);
if ((PROTOCOL_NUMBER)buffer[3] == PROTOCOL_NUMBER.ALARM_DATA)
{
//send second response of alarm packet
Utils.SendAlarmSecondResponse(client, buffer);
}
await stream.WriteAsync(response, 0, response.Length).ConfigureAwait(false);
Console.WriteLine(string.Format("{0} response sent.", (PROTOCOL_NUMBER)buffer[3]));
}
else
{
client.Close();
client.Dispose();
Console.WriteLine("Invalid packet recieved : " + buffer[3]);
Console.WriteLine(Utils.BytesToString(buffer));
}
}
if (Utils.IsVaidProtocol((PROTOCOL_NUMBER)buffer[3]) && (PROTOCOL_NUMBER)buffer[3] != PROTOCOL_NUMBER.LOGIN_MESSAGE)
{
Parser.Parse((PROTOCOL_NUMBER)buffer[3], imei, stream, buffer);
}
else if ((PROTOCOL_NUMBER)buffer[3] != PROTOCOL_NUMBER.LOGIN_MESSAGE)
{
client.Close();
client.Dispose();
Console.WriteLine("Invalid protocol : " + (PROTOCOL_NUMBER)buffer[3]);
}
}
}
}
public async static void SendAlarmSecondResponse(TcpClient client , byte[] buffer)
{
try
{
NetworkStream stream = client.GetStream();
UInt16 sendCRC = 0;
int messageLength = buffer[2];
//skip start bytes, message length. then go back 4 bytes (CRC and serial number)
byte[] serialNumber = buffer.Skip(2 + 1 + messageLength - 4).Take(2).ToArray();
int alarmDataAddressPacketLen = alarmDataAddressResponse.Length - 5;
alarmDataAddressResponse[2] = (byte)(alarmDataAddressPacketLen & 0xFF);
serialNumber.CopyTo(alarmDataAddressResponse, alarmDataAddressPacketLen - 1);
sendCRC = CRCBytes(alarmDataAddressResponse.Skip(2).Take(alarmDataAddressPacketLen - 1).ToArray());
alarmDataAddressResponse[alarmDataAddressPacketLen + 1] = (byte)((sendCRC >> 8) & 0xFF);
alarmDataAddressResponse[alarmDataAddressPacketLen + 2] = (byte)((sendCRC) & 0xFF);
await stream.WriteAsync(alarmDataAddressResponse, 0, alarmDataAddressResponse.Length).ConfigureAwait(false);
}
catch (Exception ex)
{
throw ex;
}
}

TCP is not message-oriented, it's stream-oriented.
You are likely reading more than one of your application-level "packets" into buffer, and you only parse the first, then throw the rest of the buffer away.
The inverse can also happen; there's no guarantee that you read a full application-level packet with a single read call.

Related

TcpListener write to ClientWebSocket

Im currently creating a project that will run in a browser & has an c# server connected.
The Server uses an TcpListener to accept connections & receive messages, but I want the server to be able to respond to the client. This has given me a few issues.
Here is the code for my client:
private ClientWebSocket socket;
internal async Task InitAsync(string host, int port, GamePacketParser parser)
{
Logger.Info("Setting up the socket connection...");
socket = new ClientWebSocket();
await socket.ConnectAsync(new Uri($"ws://{host}:{port}/"), CancellationToken.None);
Logger.Info("Successfully established the connection.");
this.parser = parser;
buffer = new byte[GameSocketManagerStatics.BUFFER_SIZE];
Task.Run(recieve);
}
private async Task recieve()
{
Logger.Debug("Starting Reciever.....");
var result = await socket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
var packet = new byte[result.Count];
Array.Copy(buffer, packet, result.Count);
///parser.handlePacketData(packet);
Logger.Debug($"Recieved: {Encoding.UTF8.GetString(packet)}");
///Task.Run(recieve); //Start receiving again
}
public async Task SendData(byte[] data)
{
Logger.Debug("Triggerd send");
string packet = BitConverter.ToString(data);
await socket.SendAsync(new ArraySegment<byte>(data), WebSocketMessageType.Text, true, CancellationToken.None);
Logger.Info($"Sended Data: {packet}");
}
The code above simply connects to the server over a web socket. Sending packets works fine. The second the server sends data back, the client won't send any data anymore to the server. Like its stuck.
static void Main(string[] args)
{
string ip = "127.0.0.1";
int port = 30000;
var server = new TcpListener(IPAddress.Parse(ip), port);
server.Start();
Console.WriteLine("Server has started on {0}:{1}, Waiting for a connection...", ip, port);
TcpClient client = server.AcceptTcpClient();
Console.WriteLine("A client connected.");
NetworkStream stream = client.GetStream();
if (Regex.IsMatch(s, "^GET", RegexOptions.IgnoreCase))
{
Console.WriteLine("=====Handshaking from client=====\n{0}", s);
// 1. Obtain the value of the "Sec-WebSocket-Key" request header without any leading or trailing whitespace
// 2. Concatenate it with "258EAFA5-E914-47DA-95CA-C5AB0DC85B11" (a special GUID specified by RFC 6455)
// 3. Compute SHA-1 and Base64 hash of the new value
// 4. Write the hash back as the value of "Sec-WebSocket-Accept" response header in an HTTP response
string swk = Regex.Match(s, "Sec-WebSocket-Key: (.*)").Groups[1].Value.Trim();
string swka = swk + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
byte[] swkaSha1 = System.Security.Cryptography.SHA1.Create().ComputeHash(Encoding.UTF8.GetBytes(swka));
string swkaSha1Base64 = Convert.ToBase64String(swkaSha1);
// HTTP/1.1 defines the sequence CR LF as the end-of-line marker
byte[] response = Encoding.UTF8.GetBytes(
"HTTP/1.1 101 Switching Protocols\r\n" +
"Connection: Upgrade\r\n" +
"Upgrade: websocket\r\n" +
"Sec-WebSocket-Accept: " + swkaSha1Base64 + "\r\n\r\n");
stream.Write(response, 0, response.Length);
}
byte[] message = Encoding.UTF8.GetBytes("Connection is established");
stream.Write(message, 0, message.Length);
}
The problem is probably because it is not encoded for WebSockets, but I tried a lot of online solutions for encoding (For example: How can I send and receive WebSocket messages on the server side?) But even with those encoders, it did not seem to solve the problem.
Thanks for your help in advance. Im still new to WebSockets, so spoonfeeding is allowed.
aepot your answer is a good one, but i really wanted my server on the TCP level, I would have needed to change to much code if I wanted to use it on my official server that uses sockets.
I have been doing some more digging into WebSockets, after some searching I figured it out, I basically needed to send a header before sending the data. I did not know how to create that header, but I found some code online that did. (I have been searching for about 12 hours :?)
The solution:
protected int GetHeader(bool finalFrame, bool contFrame)
{
int header = finalFrame ? 1 : 0;//fin: 0 = more frames, 1 = final frame
header = (header << 1) + 0;//rsv1
header = (header << 1) + 0;//rsv2
header = (header << 1) + 0;//rsv3
header = (header << 4) + (contFrame ? 0 : 1);//opcode : 0 = continuation frame, 1 = text
header = (header << 1) + 0;//mask: server -> client = no mask
return header;
}
protected byte[] IntToByteArray(ushort value)
{
var ary = BitConverter.GetBytes(value);
if (BitConverter.IsLittleEndian)
{
Array.Reverse(ary);
}
return ary;
}
public static IEnumerable<string> SplitInGroups(this string original, int size)
{
var p = 0;
var l = original.Length;
while (l - p > size)
{
yield return original.Substring(p, size);
p += size;
}
yield return original.Substring(p);
}
public static void SendMessage(string packet) {
Queue<string> que = new Queue<string>(packet.SplitInGroups(125)); //Make it so the message is never longer then 125 (Split the message into parts & store them in a queue)
int len = que.Count;
while (que.Count > 0)
{
var header = GetHeader(
que.Count > 1 ? false : true,
que.Count == len ? false : true
); //Get the header for a part of the queue
byte[] list = Encoding.UTF8.GetBytes(qui.Dequeue()); //Get part of the message out of the queue
header = (header << 7) + list.Length; //Add the length of the part we are going to send
//Send the header & message to client
stream.write(IntToByteArray((ushort)header));
stream.write(list);
}
}
I have not coded this myself, but sadly I cant find the link where I got it from to credit the person who did.

TCP Listener Stop Listening In Windows Form

I am working on Tcp connection to send messages between two pc it work fine in console application case but in Windows Form the listener is stop to listen it does not listen continuously and throw this exception.
Exception:
Not listening. you must call the start() method before calling this method.
Here is my code.
Code:
public static void TcpListener()
{
TcpListener server = null;
try
{
// Set the TcpListener on port 13000.
Int32 port = 8888;
IPAddress localAddr = IPAddress.Parse(Getlocalip());
// TcpListener server = new TcpListener(port);
server = new TcpListener(localAddr, port);
// Start listening for client requests.
server.Start();
// Buffer for reading data
Byte[] bytes = new Byte[256];
String data = null;
// Enter the listening loop.
Thread t = new Thread(() =>
{
while (true)
{
MessageBox.Show("Waiting for a connection... ");
// Perform a blocking call to accept requests.
// You could also user server.AcceptSocket() here.
TcpClient client = server.AcceptTcpClient();
MessageBox.Show("Server Connected!");
data = null;
// Get a stream object for reading and writing
NetworkStream stream = client.GetStream();
int i;
// Loop to receive all the data sent by the client.
while ((i = stream.Read(bytes, 0, bytes.Length)) != 0)
{
// Translate data bytes to a ASCII string.
data = System.Text.Encoding.ASCII.GetString(bytes, 0, i);
// Console.WriteLine("Received: {0}", data);
if (data == "pbrush")
{
Runprocess("start " + data);
byte[] msg = System.Text.Encoding.ASCII.GetBytes(data + " opened successfully");
// Send back a response.
stream.Write(msg, 0, msg.Length);
}
if (data == "calc")
{
Runprocess("start " + data);
byte[] msg = System.Text.Encoding.ASCII.GetBytes(data + " opened successfully");
// Send back a response.
stream.Write(msg, 0, msg.Length);
}
if (data.ToString() == "getmac")
{
string result = Runprocess(data, true);
byte[] msg = System.Text.Encoding.ASCII.GetBytes(result);
// Send back a response.
stream.Write(msg, 0, msg.Length);
}
if (data.ToString() == "tree d:")
{
string result = Runprocess(data, true);
byte[] msg = System.Text.Encoding.ASCII.GetBytes(result);
// Send back a response.
stream.Write(msg, 0, msg.Length);
}
if (data.ToString() == "ipconfig")
{
string result = Runprocess(data, true);
byte[] msg = System.Text.Encoding.ASCII.GetBytes(result);
// Send back a response.
stream.Write(msg, 0, msg.Length);
}
if (data.ToString() == "facebook")
{
Runprocess("start " + data);
byte[] msg = System.Text.Encoding.ASCII.GetBytes(data + " opened successfully");
// Send back a response.
stream.Write(msg, 0, msg.Length);
}
// Process the data sent by the client.
data = data.ToUpper();
Console.WriteLine("Sent");
}
// Shutdown and end connection
client.Close();
}
});
t.IsBackground = true;
t.Start();
}
catch (SocketException e)
{
Console.WriteLine("SocketException: {0}", e);
}
finally
{
// Stop listening for new clients.
server.Stop();
}
Console.WriteLine("\nHit enter to continue...");
Console.Read();
}
Your problem is very simple - You are calling the server.Stop() in the finally block. And since in the try block you are just starting a thread, it immediately skips to the finally block.
You are, indeed, waiting for a key in the console but that's already after you've stopped the server.
So, first you should add a try-catch block inside the thread, because currently you won't be catching any exceptions that occurs there.
Second, move the Console.Read() before the server.Stop().

C# Socket does not send complete data

I am trying to create a client/server application where a server sends commands to clients and clients send result back. The clients send data like this:
5|Hello
5 is the length of the string which is sent because then the server knows howmany characters it should receive before it should do something with that data. I tried to do that with this code:
private static void ReceiveCallback(IAsyncResult AR)
{
try
{
while (!Encoding.ASCII.GetString(_buffer).Contains("|"))
{
}
string[] a = Encoding.ASCII.GetString(_buffer).Split('|');
while (Encoding.ASCII.GetString(_buffer).Length < (Int32.Parse(a[0]) + a[0].Length + 1))
{
}
Socket socket = (Socket)AR.AsyncState;
int received = socket.EndReceive(AR);
byte[] dataBuf = new byte[received];
Array.Copy(_buffer, dataBuf, received);
string text = Encoding.ASCII.GetString(dataBuf);
if (!text.Contains("GET") && !text.Contains("HTTP") && text != null)
{
Console.WriteLine(DateTime.Now.ToString("h:mm:ss tt") + ":" + text);
}
socket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), socket);
}
catch
{
}
}
but this still does not give me the correct result. Also the CPU goes very high.
Picture of the result:
Can someone explain me why this happens? Thanks!
try to replace Encoding.ASCIIto Encoding.UTF8.
It can fix you issue.
Do note that you must to use the same encoding on both sides (sending and receiving data).
I hope it helps you.
have you tried using TcpClient? it can be way easier and gives you more control.
something like;
//make connection
NetworkStream stream = null;
socket = new TcpClient();
socket.Connect("192.168.12.12", 15879);
if (socket.Connected) {
stream = socket.GetStream();
}
//and than wait for tcp packets.
connectionThread = new Thread(ListenServer);
connectionThread.Start();
private void ListenToServer() {
Byte[] data = new Byte[1024];
String message = String.Empty;
Int32 dataLength = 0;
while (socket.Connected) {
try {
while (stream.DataAvailable) {
dataLength = stream.Read(data, 0, data.Length);
message = System.Text.Encoding.UTF8.GetString(data, 0, dataLength);
//do what ever you need here
Thread.Sleep(1);
}
} catch (Exception ex) {
}
Thread.Sleep(100);
}
moreover %1 cpu load!

Proxy server does not load images

I'm trying to make a proxy server with C#.
Here's my code:
static void Main(string[] args)
{
TcpListener server = null;
try
{
// Set the TcpListener on port 13000.
Int32 port = 13000;
IPAddress localAddr = IPAddress.Parse("127.0.0.1");
// TcpListener server = new TcpListener(port);
server = new TcpListener(localAddr, port);
// Start listening for client requests.
server.Start();
// Buffer for reading data
Byte[] bytes = new Byte[256];
String data = null;
WebRequest request;
WebResponse response;
// Enter the listening loop.
while (true)
{
Console.Write("Waiting for a connection... ");
// Perform a blocking call to accept requests.
// You could also user server.AcceptSocket() here.
TcpClient client = server.AcceptTcpClient();
Console.WriteLine("Connected!");
data = null;
// Get a stream object for reading and writing
NetworkStream stream = client.GetStream();
int i;
String[] input;
// Loop to receive all the data sent by the client.
while (stream.DataAvailable)
{
data = null;
i = stream.Read(bytes, 0, bytes.Length);
// Translate data bytes to a ASCII string.
data = System.Text.Encoding.ASCII.GetString(bytes, 0, i);
Console.WriteLine(String.Format("Received: {0}", data));
input = data.Split();
Console.WriteLine("\n\r\n input[1]" + input[1] + "\n");
Stream dataStream;
StreamReader reader;
string responseFromServer;
try
{
request = WebRequest.Create(input[1]);
response = request.GetResponse();
// Process the data sent by the client.
data = data.ToUpper();
dataStream = response.GetResponseStream();
// Open the stream using a StreamReader for easy access.
reader = new StreamReader(dataStream);
// Read the content.
responseFromServer = reader.ReadToEnd();
// Display the content
Console.WriteLine(responseFromServer);
// Clean up the streams and the response.
byte[] msg = System.Text.Encoding.ASCII.GetBytes(responseFromServer);
// Send back a response.
stream.Write(msg, 0, msg.Length);
// Console.WriteLine("Sent: {0}", data);
//stream.Write();
reader.Close();
response.Close();
}
catch (System.UriFormatException e)
{
Console.WriteLine("Exception due to" + e.Data);
Console.WriteLine("Input[1] = " + input[1]);
}
data = null;
}
// Shutdown and end connection
client.Close();
}
}
catch (SocketException e)
{
Console.WriteLine("SocketException: {0}", e);
}
finally
{
// Stop listening for new clients.
server.Stop();
}
Console.WriteLine("\nHit enter to continue...");
Console.Read();
}
It does not work for ssl requests but seems to work for http.
However, it does not load any images.
I'm using Firefox as the browser.
Any ideas why?
Also is this the best way to make a proxy server? Are there any other methods?
After a bit of testing, I wrote my own code.
using System;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Threading;
using System.Text;
namespace SharpProxy
{
class MainClass
{
private static void StartAcceptingClient(IAsyncResult ar)
{
var tcpClient = server.EndAcceptTcpClient(ar);
server.BeginAcceptTcpClient(new AsyncCallback(StartAcceptingClient), null);
// Read the data stream from the client.
NetworkStream stream = tcpClient.GetStream();
byte[] buffer = new byte[256];
Console.WriteLine("====== GOT A NEW TCP CLIENT ====== " + tcpClient.Client.RemoteEndPoint.ToString());
int read = stream.Read(buffer, 0, 1);
MemoryStream saved = new MemoryStream();
saved.Write(buffer, 0, read);
bool isValid = false;
while (read > 0 )
{
read = stream.Read(buffer, 0, 1);
saved.Write(buffer, 0, read);
//Check if the last four bytes were a double \r\n.
var aBytes = saved.ToArray();
int len = aBytes.Length;
if (aBytes.Length >= 4 && aBytes[len - 1] == '\n' && aBytes[len - 2] == '\r' && aBytes[len - 3] == '\n' && aBytes[len - 4] == '\r')
{
isValid = true;
break;
}
}
Console.WriteLine("End of receive.");
string originalRequest = Encoding.ASCII.GetString(saved.ToArray());
byte[] origBytes = saved.ToArray();
saved.Close();
Console.WriteLine(originalRequest);
if (!isValid)
{
Console.WriteLine("This wasn't a valid request");
return;
}
//Find the hoster and do our own request.
string host = originalRequest.Split(new char[] { '\n' }).First(line => line.StartsWith("Host:"));
host = host.Substring(5).Trim(); //Cut of rest.
Console.WriteLine("The host is: " + host);
//Do our own request.
try
{
Socket sProxy = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
sProxy.Connect(host, 80);
sProxy.Send(origBytes);
//Now route everything between the tcpclient and this socket...
//create the state object
var state = new ProxyState() { ourSocket = sProxy, incomingClient = stream };
sProxy.BeginReceive(state.ReceiveBuffer, 0, state.ReceiveBuffer.Length, SocketFlags.None, new AsyncCallback(Receiver), state);
stream.BeginRead(state.SendBuffer, 0, state.SendBuffer.Length, new AsyncCallback(SendToHTTPServer), state);
}
catch (Exception) { Console.WriteLine("Exception while doing our own request"); }
}
static TcpListener server = null;
public static void Main(string[] args)
{
try
{
// Set the TcpListener on port 13000.
Int32 port = 13000;
IPAddress localAddr = IPAddress.Parse("0.0.0.0");
// TcpListener server = new TcpListener(port);
server = new TcpListener(localAddr, port);
// Start listening for client requests.
server.Start();
Console.WriteLine("Server started on " + server.LocalEndpoint.ToString());
server.BeginAcceptTcpClient(new AsyncCallback(StartAcceptingClient), null);
while (true)
Thread.Sleep(10);
}
catch (Exception) { Console.WriteLine("Setting up the server failed"); }
}
private static void SendToHTTPServer(IAsyncResult ar)
{
try
{
ProxyState back = (ProxyState)ar.AsyncState;
int rec = back.incomingClient.EndRead(ar);
//Push this content to the server
back.ourSocket.Send(back.SendBuffer.Take(rec).ToArray());
back.incomingClient.BeginRead(back.SendBuffer, 0, back.SendBuffer.Length, new AsyncCallback(SendToHTTPServer), back);
}
catch (Exception e) { Console.WriteLine("Exc. when sending to server: " + e.ToString()); }
}
static void Receiver(IAsyncResult state)
{
try
{
ProxyState back = (ProxyState)state.AsyncState;
int rec = back.ourSocket.EndReceive(state);
//Set up the back and forth connections
back.incomingClient.Write(back.ReceiveBuffer, 0, rec);
back.ourSocket.BeginReceive(back.ReceiveBuffer, 0, back.ReceiveBuffer.Length, SocketFlags.None, new AsyncCallback(Receiver), back);
}
catch (Exception e) { Console.WriteLine("Exc. when receiving from client: " + e.ToString()); }
}
//Every proxy connection has an end an and a beginning, plus a
//Sending buffer and a receive buffer
class ProxyState
{
public NetworkStream incomingClient { get; set; }
public Socket ourSocket { get; set; }
private byte[] buffReceive = new byte[512];
private byte[] buffSend = new byte[512];
public byte[] ReceiveBuffer { get { return buffReceive; } set { buffReceive = value; } }
public byte[] SendBuffer { get { return buffSend; } set { buffSend = value; } }
}
}
}
Here's how it works: I listen on a port, and wait for a HTTP request. This is ended by a double carriage return and a linefeed, a \r\n\r\n. As soon as that happens, I try to parse the original host from the request with a Linq statement. I open my own socket to the server, and make use of the asynchronous callbacks. Basically, you need to write everything that comes from the proxy-iniator to the HTTP-Server, and everything that the HTTP-Server sends back needs to be pushed back to the original client aswell. This is why I set up my own state-object, which just saves the incomming client and the Socket, which is connected to the original HTTP server. And as such, communication can happen and I act as a proxy server.
Here's a screenshot with all the connections done right:
This proxy server is far from perfect, but the basic concept should be clear. This gave me some inspiration.
You use a streamreader on binary image data, that is not going to work. Not every binary is a valid ASCII encoded string. You should read the response as binary, and write it to the other stream as binary as well. You can try to convert it to ascii to print it to the console, but do not use the converted text to respond, because all the non-valid ascii characters will be converted to ?-s. I did modify your code to first read the response in a MemoryStream, and write that back. The data written to the console is still converted, but not user anywhere else.
static void Main(string[] args)
{
TcpListener server = null;
try
{
// Set the TcpListener on port 13000.
Int32 port = 13000;
IPAddress localAddr = IPAddress.Parse("127.0.0.1");
// TcpListener server = new TcpListener(port);
server = new TcpListener(localAddr, port);
// Start listening for client requests.
server.Start();
// Buffer for reading data
Byte[] bytes = new Byte[256];
String data = null;
WebRequest request;
WebResponse response;
// Enter the listening loop.
while (true)
{
Console.Write("Waiting for a connection... ");
// Perform a blocking call to accept requests.
// You could also user server.AcceptSocket() here.
TcpClient client = server.AcceptTcpClient();
Console.WriteLine("Connected!");
data = null;
// Get a stream object for reading and writing
NetworkStream stream = client.GetStream();
int i;
String[] input;
// Loop to receive all the data sent by the client.
while (stream.DataAvailable)
{
data = null;
i = stream.Read(bytes, 0, bytes.Length);
// Translate data bytes to a ASCII string.
data = System.Text.Encoding.ASCII.GetString(bytes, 0, i);
Console.WriteLine(String.Format("Received: {0}", data));
input = data.Split();
Console.WriteLine("\n\r\n input[1]" + input[1] + "\n");
Stream dataStream;
StreamReader reader;
string responseFromServer;
try
{
request = WebRequest.Create(input[1]);
response = request.GetResponse();
// Process the data sent by the client.
data = data.ToUpper();
dataStream = response.GetResponseStream();
MemoryStream ms = new MemoryStream();
dataStream.CopyTo(ms);
ms.Position = 0;
// Open the stream using a StreamReader for easy access.
reader = new StreamReader(ms);
// Read the content.
responseFromServer = reader.ReadToEnd();
// Display the content
Console.WriteLine(responseFromServer);
// Clean up the streams and the response.
byte[] msg = ms.ToArray();
// Send back a response.
stream.Write(msg, 0, msg.Length);
// Console.WriteLine("Sent: {0}", data);
//stream.Write();
reader.Close();
response.Close();
}
catch (System.UriFormatException e)
{
Console.WriteLine("Exception due to" + e.Data);
Console.WriteLine("Input[1] = " + input[1]);
}
data = null;
}
// Shutdown and end connection
client.Close();
}
}
catch (SocketException e)
{
Console.WriteLine("SocketException: {0}", e);
}
finally
{
// Stop listening for new clients.
server.Stop();
}
Console.WriteLine("\nHit enter to continue...");
Console.Read();
}

Send text string via TCP?

I just read and tested code of this great article in order to understand TCP Client and Server.
Now I need to do (I hope) really simple thing I need to send some string from TCP Client To TCP Server.
The string is serialized object and it is a XML in fact.
What I don't understand where I have to include this code in TCP Client and also in the TCP server.
TCP Client:
static void Main(string[] args)
{
while (true)
{
String server = "192.168.2.175"; // args[0]; // Server name or IP address
// Convert input String to bytes
byte[] byteBuffer = Encoding.ASCII.GetBytes("1024"); // Encoding.ASCII.GetBytes(args[1]);
// Use port argument if supplied, otherwise default to 8080
int servPort = 1311; // (args.Length == 3) ? Int32.Parse(args[2]) : 8080;//7 ;
TcpClient client = null;
NetworkStream netStream = null;
try
{
// Create socket that is connected to server on specified port
client = new TcpClient(server, servPort);
Console.WriteLine("Connected to server... sending echo string");
netStream = client.GetStream();
// Send the encoded string to the server
netStream.Write(byteBuffer, 0, byteBuffer.Length);
Console.WriteLine("Sent {0} bytes to server...", byteBuffer.Length);
int totalBytesRcvd = 0; // Total bytes received so far
int bytesRcvd = 0; // Bytes received in last read
// Receive the same string back from the server
while (totalBytesRcvd < byteBuffer.Length)
{
if ((bytesRcvd = netStream.Read(byteBuffer, totalBytesRcvd,
byteBuffer.Length - totalBytesRcvd)) == 0)
{
Console.WriteLine("Connection closed prematurely.");
break;
}
totalBytesRcvd += bytesRcvd;
}
Console.WriteLine("Received {0} bytes from server: {1}", totalBytesRcvd,
Encoding.ASCII.GetString(byteBuffer, 0, totalBytesRcvd));
}
catch (Exception ex)
{
// http://stackoverflow.com/questions/2972600/no-connection-could-be-made-because-the-target-machine-actively-refused-it
Console.WriteLine(ex.Message);
}
finally
{
if (netStream != null)
netStream.Close();
if (client != null)
client.Close();
}
Thread.Sleep(1000);
}
}
TCP Server
class Program
{
private const int BUFSIZE = 32; // Size of receive buffer
static void Main(string[] args)
{
int servPort = 1311; // (args.Length == 1) ? Int32.Parse(args[0]) : 8080;
TcpListener listener = null;
try
{
// Create a TCPListener to accept client connections
listener = new TcpListener(IPAddress.Any, servPort);
listener.Start();
}
catch (SocketException se)
{
// IPAddress.Any
Console.WriteLine(se.ErrorCode + ": " + se.Message);
//Console.ReadKey();
Environment.Exit(se.ErrorCode);
}
byte[] rcvBuffer = new byte[BUFSIZE]; // Receive buffer
int bytesRcvd; // Received byte count
for (; ; )
{ // Run forever, accepting and servicing connections
// Console.WriteLine(IPAddress.Any);
TcpClient client = null;
NetworkStream netStream = null;
//Console.WriteLine(IPAddress.None);
try
{
client = listener.AcceptTcpClient(); // Get client connection
netStream = client.GetStream();
Console.Write("Handling client - ");
// Receive until client closes connection, indicated by 0 return value
int totalBytesEchoed = 0;
while ((bytesRcvd = netStream.Read(rcvBuffer, 0, rcvBuffer.Length)) > 0)
{
netStream.Write(rcvBuffer, 0, bytesRcvd);
totalBytesEchoed += bytesRcvd;
}
Console.WriteLine("echoed {0} bytes.", totalBytesEchoed);
// Close the stream and socket. We are done with this client!
netStream.Close();
client.Close();
}
catch (Exception e)
{
Console.WriteLine(e.Message);
netStream.Close();
}
}
}
}
Converting my Comments into an answer:
I strongly suggest you use WCF, instead of implementing all the stuff yourself. In WCF, you create the interfaces (Service Contracts) and implementations (Services) and the framework abstracts all the communication / protocol details out.
You can use WCF Duplex to have two-way communications between server and client
The example that you give is a simple 'mirror', where the TCP server sends back to the client the data that it receives from it.
The data that you want to send is in the byteBuffer variable (you are currently sending the text "1024", I believe). So instead of initializing it with "1024", you could initialize it with the XML-serialized data that you want.
On the client side, conversely, instead of echoing the data back to the client, you could simply do whatever you need on the server side with the data, that is your XML object.

Categories