Read data from socket, send response and close - c#

I am working on a c# and php project where the PHP script opens a socket to a c# program and the c# program will read the data and then send a response back.
In the PHP script I have the following:
echo "Opening Client";
$fp = fsockopen("127.0.0.1", 12345, $errno, $errstr, 30);
if (!$fp)
{
echo "Error: $errstr ($errno)<br />";
}
else
{
$out = "GET / HTTP/1.1\r\n";
$out .= "Host: 127.0.0.1\r\n";
$out .= "Connection: Close\r\n\r\n";
fwrite($fp, $out);
while (!feof($fp))
{
echo fgets($fp, 128);
}
fclose($fp);
}
In the C# project I have the following:
public void startListen()
{
int port = 12345;
IPAddress serverAddress = IPAddress.Parse("127.0.0.1");
TcpListener listener = new TcpListener(serverAddress, 12345);
listener.Start();
TcpClient client = listener.AcceptTcpClient();
NetworkStream stream = client.GetStream();
byte[] data = new byte[client.ReceiveBufferSize];
int bytesRead = stream.Read(data, 0, Convert.ToInt32(client.ReceiveBufferSize));
string request = Encoding.ASCII.GetString(data, 0, bytesRead);
Console.WriteLine(request);
Console.ReadLine();
The PHP script seems to stay waiting and doesn't finish, I'm guessing its being its because the socket on the c# app to send a response back but I have no idea how to do this. Another problem, in the C# I need to have Console.ReadLine() otherwise the c# program will exit but the PHP Script does then finish as expected.
Basically, what I want to know is this the best way to read the data that is sent on the socket, what is the best way to keep the program running so it keep on listening on the socket and how I send back a reply so that the php script can finish.
Thanks for any help you can provide.

I managed to figure this out, after processing the data I need to then send a stream.write which is what sends the reply back.
Below is the code
int port = 12345;
IPAddress serverAddress = IPAddress.Parse("127.0.0.1");
TcpListener listener = new TcpListener(serverAddress, port);
listener.Start();
while (true)
{
TcpClient client = listener.AcceptTcpClient();
NetworkStream stream = client.GetStream();
byte[] data = new byte[client.ReceiveBufferSize];
int bytesRead = stream.Read(data, 0, Convert.ToInt32(client.ReceiveBufferSize));
string request = Encoding.ASCII.GetString(data, 0, bytesRead);
Console.WriteLine(request);
byte[] msg = System.Text.Encoding.ASCII.GetBytes("200 OK");
// Send back a response.
stream.Write(msg, 0, msg.Length);
client.Close();
}
Thanks for your help

Mr. Boardy's solution is correct but I think doing this by socket is better.
So the socket solution is:
private void Form3_Load(object sender, EventArgs e)
{
sc_listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint ip_local = new IPEndPoint(IPAddress.Loopback, 1225);
sc_listener.Bind(ip_local);
sc_listener.Listen(10);
AsyncCallback callback = new AsyncCallback(procces_incoming_socket);
sc_listener.BeginAccept(callback, sc_listener);
}
void procces_incoming_socket(IAsyncResult socket_object)
{
Socket sc_listener = ((Socket)socket_object.AsyncState).EndAccept(socket_object);
AsyncCallback receive = new AsyncCallback(receive_data);
buffer = new byte[100];
sc_listener.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, receive, sc_listener);
}
void receive_data(IAsyncResult socket)
{
// the system need to wait so i make a loop when it gets data
//i end the loop by flag=false
bool flag = true;
Socket re_socket = ((Socket)socket.AsyncState);
while(flag)
{
int bytes_recieved = re_socket.EndReceive(socket);
string data = UTF8Encoding.UTF8.GetString(buffer);
if (textBox1.InvokeRequired)
{
// for cross thread problem
textBox1.Invoke(new MethodInvoker(delegate { textBox1.Text = data; }));
}
else
{
textBox1.Text = data;
}
flag = false;
}
string back_data = "my pm socket back";
byte[] buffers = new byte[50];
buffers = UTF8Encoding.UTF8.GetBytes(back_data);
re_socket.Send(buffers);
// if the socket is not closed php will load for maximum required time and then error
re_socket.Close();
//start for next listening (O-0)
AsyncCallback callback = new AsyncCallback(procces_incoming_socket);
sc_listener.BeginAccept(callback, sc_listener);
}

I am not a php guy by any stretch of the imagination so my answer is contingent upon php being able to respond correctly. On the C# side, create a while/do-while loop that continues to run to accept the next incoming request. Here's a simple example:
http://www.csharp-examples.net/socket-send-receive/
Make sure to set the NoDelay option so that the information is flushed.

Related

I have multiple TcpClient connections, how do I select a specific one?

I have a TCP Client
Log.Warn("Trying to connect to " + IP);
TcpClient client = new TcpClient(IP, Port);
string command = "";
while (!command.Contains("quit"))
{
Log.WriteSingle("localhost#", ConsoleColor.DarkYellow);
Log.WriteSingle(IP + ":", ConsoleColor.Yellow);
command = Console.ReadLine();
byte[] data = Encoding.ASCII.GetBytes(command);
NetworkStream stream = client.GetStream();
stream.Write(data, 0, data.Length);
Log.Success("Sent command to network.");
// Buffer to store the response bytes.
data = new Byte[256];
// String to store the response ASCII representation.
String responseData = String.Empty;
// Read the first batch of the TcpServer response bytes.
Int32 bytes = stream.Read(data, 0, data.Length);
responseData = System.Text.Encoding.ASCII.GetString(data, 0, bytes);
Log.Write("Server Says: " + responseData, ConsoleColor.DarkYellow);
}
and a TCP Server
while(true)
{
Log.Write("Waiting for connection...");
TcpClient client = server.AcceptTcpClient();
Log.Success("Connected! ");
//Update list (Currently useless)
clientList.Add(client);
Thread t = new Thread(new ThreadStart(()=>ConnectClient(client,bytes,data)));
t.Start();
}
public static void ConnectClient(TcpClient _client, byte[] _bytes, string _data)
{
_data = null;
NetworkStream stream = _client.GetStream();
int i;
while((i = stream.Read(_bytes,0,_bytes.Length))!=0)
{
_data = System.Text.Encoding.ASCII.GetString(_bytes,0,i);
Log.Write("Recieved: "+_data, ConsoleColor.Cyan);
//Send back to client
_data = _data.ToUpper();
byte[] msg = System.Text.Encoding.ASCII.GetBytes(_data);
stream.Write(msg,0,msg.Length);
Log.Write("Sent: "+_data);
}
_client.Close();
}
I have it setup so the server listens to client connections and pop them off in a new thread once they connect. The client can send the server a string, and the server reflects it back.
I assume I can use a dictionary to assign an ID and store the client, or even just a simple List.
How would I structure it so I can add them to a List or a Dictionary and still be able to connect multiple clients?
Thanks
Put your accept() loop in a thread of its own. It can add to the list each time a new client connects.
Leave your main thread to manage all the client threads, including the accept() thread.

Discovering a Belkin Wemo switch in C# using UdpClient and JoinMulticastGroup

I am trying to discover a Belkin Wemo switch using C#. I am sending SSDP over the network to get back a response from the switch.
The following snippet creates a socket, sends SSDP and waits for 2 seconds to receive an answer. If nothing is read, it starts all again.
bool repeat = true;
while (repeat)
{
UdpClient udpClient = null;
try
{
// Creates the socket.
udpClient = new UdpClient(10140);
udpClient.Client.ReceiveTimeout = 2000;
IPAddress broadcastIpAddress = IPAddress.Parse("239.255.255.250");
IPEndPoint broadcastIpEndPoint = new IPEndPoint(broadcastIpAddress, 1900);
udpClient.JoinMulticastGroup(broadcastIpAddress);
// Sends SSDP.
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.Append("M-SEARCH * HTTP/1.1\r\n");
stringBuilder.Append("ST: urn:Belkin:service:basicevent:1\r\n");
stringBuilder.Append("MX: 1\r\n");
stringBuilder.Append("MAN: \"ssdp:discover\"\r\n");
stringBuilder.Append("HOST: 239.255.255.250:1900\r\n");
stringBuilder.Append("\r\n");
byte[] bytesToSend = Encoding.UTF8.GetBytes(stringBuilder.ToString());
udpClient.Send(bytesToSend, bytesToSend.Length, broadcastIpEndPoint);
// Receives response.
IPEndPoint remoteIpEndPoint = new IPEndPoint(IPAddress.Any, 0);
byte[] receivedBytes = udpClient.Receive(ref remoteIpEndPoint);
string receivedString = Encoding.UTF8.GetString(receivedBytes);
Console.WriteLine(receivedString);
repeat = false;
}
catch (SocketException) { }
finally
{
udpClient.Close();
}
}
Most of the time, a response is returned by the switch. However, sometimes it loops indefinitely without getting any feedback.
I am using Wireshark. In the second case, it happens that no SSDP is sent. I have no explanation about that. My system is Windows 7, maybe it helps...

C# and Processing socket communication

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.

Synchronization in C# networking

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.

setting up a tcp server to communicate with android and kinect

I am making a dual app with android and kinect. I want to be able to send notifications to the android app from the kinect. I was told that the best way to accomplish this is to set up a simple tcp server. I tried to set it up by using the tutorial at this <link>. The tutorial however isn't descriptive enough for me and I am unable to make it work. The guy who posted it basically posted several pieces of code without any instruction about assembling them. I need someone to either walk me through setting up this server or I need a link to a detailed tutorial. I have searched the web myself for hours but I haven't found anything useful, which is why I'm asking here.
Here's what I thought he was saying to do in that tutorial:
using System;
using System.Text;
using System.Net.Sockets;
using System.Threading;
using System.Net;
namespace TCPServerTutorial
{
class Server
{
private TcpListener tcpListener;
private Thread listenThread;
public Server()
{
this.tcpListener = new TcpListener(IPAddress.Any, 3000);
this.listenThread = new Thread(new ThreadStart(ListenForClients));
this.listenThread.Start();
}
private void HandleClientComm(object client)
{
TcpClient tcpClient = (TcpClient)client;
NetworkStream clientStream = tcpClient.GetStream();
byte[] message = new byte[4096];
int bytesRead;
while (true)
{
bytesRead = 0;
try
{
//blocks until a client sends a message
bytesRead = clientStream.Read(message, 0, 4096);
}
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();
System.Diagnostics.Debug.WriteLine(encoder.GetString(message, 0, bytesRead));
}
tcpClient.Close();
}
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));
clientThread.Start(client);
}
}
//you'll have to find a way to pass this arg
private void SendBack(TcpClient tcpClient)
{
NetworkStream clientStream = tcpClient.GetStream();
ASCIIEncoding encoder = new ASCIIEncoding();
byte[] buffer = encoder.GetBytes("Hello Client!");
clientStream.Write(buffer, 0 , buffer.Length);
clientStream.Flush();
}
}
}
But that's just me. He only ever talked about one class, so it is logical to assume all his functions are in that class.
For the client code, he pretty much just gives you the code for a function (in C#, of course) which will send some bytes to an IP address (aka, the IP of the machine your server is running on). You could put this function in any C# class and call it in whatever way you wish. He has hard coded the IP address and the message to send, but these could easily be arguments passed to the function.
private void SendToServer(){
TcpClient client = new TcpClient();
//IP of the server: currently loopback, change to whatever you want
IPEndPoint serverEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 3000);
client.Connect(serverEndPoint);
NetworkStream clientStream = client.GetStream();
ASCIIEncoding encoder = new ASCIIEncoding();
//Message being sent: "Hello Server!"
byte[] buffer = encoder.GetBytes("Hello Server!");
clientStream.Write(buffer, 0 , buffer.Length);
clientStream.Flush();
}

Categories

Resources