Transfer String via TCP/IP to multiple computers - c#

This code currently takes kinect Body data and writes it in an Excel Worksheet. I have another code that is able to create a TCP/IP connection between two computers. How would I best combine these two ideas?
I require this Joint String Data to be sent over the network and collected by another server computer, in real-time, not in an excel file. Do you have any suggestions ?
In other words, I have some Server code, but i want the server to listen for the Kinect String Data that the client code (Another computer) is generating and currently is writing it to a local excel file.
Client Side
...
_recordBody = !_recordBody;
if (_recordBody == false)
{
recordButton.Content = "Record";
return;
}
recordButton.Content = "Stop Recording";
currentTrackingID = 0;
// create a csv file and write file header
string currPath = System.IO.Directory.GetCurrentDirectory();
string folder = "recordings";
string recordPath = System.IO.Path.Combine(currPath, folder);
if (!Directory.Exists(recordPath))
{
Directory.CreateDirectory(recordPath);
}
timeRecordingStarted = DateTime.Now;
string filename = timeRecordingStarted.ToString("yyyy-MM-dd HH-mm-ss");
filename = filename + ".csv";
filePath = System.IO.Path.Combine(recordPath, filename);
string[] writtentext = {"time," + "headX," +
"headY," +
"headZ," +
"headS," +
"neckX," +
"neckY," +
"neckZ," +
"neckS," +
"spineShoulderX," +
"spineShoulderY," +
"spineShoulderZ," +
...
"handLeftY," +
"handLeftZ," +
"handLeftS," +
"handTipRightX," +
"handTipRightY," +
"handTipRightZ," +
"handTipRightS," +
"handTipLeftX," +
"handTipLeftY," +
"handTipLeftZ," +
"handTipLeftS"
};
File.WriteAllLines(filePath, writtentext);
...
Server Code
static TcpListener tcpListener = new TcpListener(10);
static void Listeners()
{
Socket socketForClient = tcpListener.AcceptSocket();
if (socketForClient.Connected)
{
Console.WriteLine("Client:"+socketForClient.RemoteEndPoint+" now connected to server.");
NetworkStream networkStream = new NetworkStream(socketForClient);
System.IO.StreamWriter streamWriter =
new System.IO.StreamWriter(networkStream);
System.IO.StreamReader streamReader =
new System.IO.StreamReader(networkStream);
{
string theString = streamReader.ReadLine();
Console.WriteLine("Message recieved by client:" + theString);
if (theString == "exit")
break;
}
streamReader.Close();
networkStream.Close();
streamWriter.Close();
//}
}
socketForClient.Close();
Console.WriteLine("Press any key to exit from server program");
Console.ReadKey();
}
public static void Main()
{
//TcpListener tcpListener = new TcpListener(10);
tcpListener.Start();
Console.WriteLine("************This is Server program************");
Console.WriteLine("How many clients are going to connect to this server?:");
int numberOfClientsYouNeedToConnect =int.Parse( Console.ReadLine());
for (int i = 0; i < numberOfClientsYouNeedToConnect; i++)
{
Thread newThread = new Thread(new ThreadStart(Listeners));
newThread.Start();
}
}
}

Related

c# HTTPS proxy (just relaying from browser -> proxy -> website -> proxy -> browser)

so I have this code where I relay all connections to the destination server, I get the response back from it in a byte[] called result, but when dealing with SSL/HTTPS the end server always return an empty response
public static byte[] ForwardRequest(byte[] requestBytes)
{
byte[] result = new byte[0];
try
{
string requestString = Encoding.UTF8.GetString(requestBytes);
string[] requestLines = requestString.Split(new string[] { Environment.NewLine }, StringSplitOptions.None);
string host = "";
int port = 80;
if (requestString.Contains("CONNECT"))
{
string connectLine = requestLines[0];
string hostWithPort = connectLine.Split(' ')[1];
host = hostWithPort.Split(':')[0];
port = Convert.ToInt32(hostWithPort.Split(':')[1]);
}
else
{
host = requestLines[1].Split(' ')[1];
if (host.Contains(":"))
{
string[] split = host.Split(':');
host = split[0];
port = Convert.ToInt32(split[1]);
}
}
Console.WriteLine("HOST:" + host + "#PORT:" + port);
TcpClient client = new TcpClient();
client.Connect(host, port);
if(client.Connected == true && requestString.Contains("CONNECT"))
{
Console.WriteLine("client connected to ssl");
}
Network.WriteBytes(client, requestBytes);
result = Network.ReadBytes(client, 10000);
if (requestString.Contains("CONNECT"))
{
string resultString = Encoding.UTF8.GetString(result);
Console.WriteLine("############BROWSER REQUEST################" + Environment.NewLine + requestString + Environment.NewLine + "############BROWSER REQUEST################");
Console.WriteLine("############WEBSITE RESPONSE###############" + Environment.NewLine + resultString + Environment.NewLine + "############WEBSITE RESPONSE###############");
Console.WriteLine("responseLenght: " + result.Length);
}
}
catch (Exception ex)
{
Console.WriteLine("Network.Forward() -> " + ex.Message);
}
return result;
}
I thought that it should work because I'm just sending raw data from browser to server and back. Again, all the other code works fine because with HTTP websites it works.
this is my console window after sending trying to talk to HTTPS

TcpListener AcceptSocket() accepts two connections for each single GET request

I have this web server program up and running, using TcpListener. The problem is that for each get request made through web browser (or chrome Postman extension), it captures two requests.
namespace Server
{
class WebServer2
{
private TcpListener listener;
private int port = 8080;
public WebServer2()
{
try
{
listener = new TcpListener(IPAddress.Parse("127.0.0.1"), port);
listener.Start();
Console.WriteLine("Listening...");
//start the thread which calls the method 'StartListen'
Thread th = new Thread(new ThreadStart(StartListen));
th.Start();
}
catch (Exception e)
{
Console.WriteLine("An Exception Occurred While Listening: " + e.ToString());
}
}
//Recieve Request
public void StartListen()
{
int iStartPos = 0;
String sRequest;
String sRequestedFile;
String sResponse = "";
while (true)
{
//Accept a new connection
Socket socket = listener.AcceptSocket();
if (socket.Connected)
{
Console.WriteLine("\nClient Connected");
Console.WriteLine("----------------");
//Receive data from the client
Byte[] bReceive = new Byte[1024];
int i = socket.Receive(bReceive, bReceive.Length, 0);
//Convert Byte to String
string sBuffer = Encoding.ASCII.GetString(bReceive);
//Only GET Request is accepted
if (sBuffer.Substring(0, 3) != "GET")
{
Console.WriteLine("Not a Get Request.");
socket.Close();
continue;
}
// Look for HTTP request
iStartPos = sBuffer.IndexOf("HTTP", 1);
// Get the HTTP text and version e.g. it will return "HTTP/1.1"
string sHttpVersion = sBuffer.Substring(iStartPos, 8);
// Extract the Requested Type and Requested file/directory
sRequest = sBuffer.Substring(0, iStartPos - 1);
//If file name not provided
if (sRequest.IndexOf(".") < 1)
{
Console.WriteLine("File name not Provided!");
socket.Close();
continue;
}
//Extract the requested file name
iStartPos = sRequest.LastIndexOf("/") + 1;
sRequestedFile = sRequest.Substring(iStartPos);
Console.WriteLine("Requested File: " + sRequestedFile);
int iTotBytes = 0;
sResponse = "";
FileStream fs = new FileStream(sRequestedFile, FileMode.Open, FileAccess.Read, FileShare.Read);
BinaryReader reader = new BinaryReader(fs);
byte[] bytes = new byte[fs.Length];
int read;
while ((read = reader.Read(bytes, 0, bytes.Length)) != 0)
{
// Read from the file and write the data to the network
sResponse = sResponse + Encoding.ASCII.GetString(bytes, 0, read);
iTotBytes = iTotBytes + read;
}
reader.Close();
fs.Close();
SendHeader(sHttpVersion, "text/html", iTotBytes, " 200 OK", ref socket);
SendToBrowser(bytes, ref socket);
socket.Send(bytes, bytes.Length, 0);
socket.Close();
}
}
}
// Overloaded Function, takes string, convert to bytes and calls
// overloaded sendToBrowserFunction.
public void SendToBrowser(String sData, ref Socket socket)
{
SendToBrowser(Encoding.ASCII.GetBytes(sData), ref socket);
}
/// Sends data to the browser (client)
public void SendToBrowser(Byte[] bSendData, ref Socket socket)
{
int numBytes = 0;
try
{
if (socket.Connected)
{
if ((numBytes = socket.Send(bSendData, bSendData.Length, 0)) == -1)
Console.WriteLine("Socket Error");
}
else
Console.WriteLine("Connection Dropped!");
}
catch (Exception e)
{
Console.WriteLine("Error: {0} ", e);
}
}
// This function send the Header Information to the client (Browser)
public void SendHeader(string sHttpVersion, string sMIMEHeader, int iTotBytes, string sStatusCode, ref Socket socket)
{
String sBuffer = "";
Byte[] bSendData;
if (sStatusCode.Equals("404") || sStatusCode.Equals("400"))
{
sBuffer = sBuffer + sHttpVersion + sStatusCode + "\r\n";
sBuffer = sBuffer + "Server: MyServer\r\n";
sBuffer = sBuffer + "Content-Length: " + 0 + "\r\n\r\n";
bSendData = Encoding.ASCII.GetBytes(sBuffer);
SendToBrowser(bSendData, ref socket);
}
else
{
sBuffer = sBuffer + sHttpVersion + sStatusCode + "\r\n";
sBuffer = sBuffer + "Server: MyServer\r\n";
sBuffer = sBuffer + "Content-Type: " + sMIMEHeader + "\r\n";
sBuffer = sBuffer + "Accept-Ranges: bytes\r\n";
sBuffer = sBuffer + "Content-Length: " + iTotBytes + "\r\n\r\n";
bSendData = Encoding.ASCII.GetBytes(sBuffer);
SendToBrowser(bSendData, ref socket);
}
}
}
}
Single request made by chrome against http://localhost:8080/page1.html
Request made by Postman Extension
The funny thing is, everything works find when I send request through my client program (using TcpClient).
I tested your server and got similar results:
Chrome automatically asks for a favicon.ico file for every request. This generates the extra GET request to your server.
Firefox doesn't do this and simply generates one request per refresh.
Then there is a second problem I experienced, which is the one in your Postman screenshot.
Chrome (including the Postman Extension running inside it) reconnects
without sending anything, so the server "hangs" until you get a
response filled with \0 (nul-characters).
This is part of Chrome's prediction service to load subsequent requests faster. You could disable this behavior under Settings (advanced) > Privacy:
In your server implementation, this results in the "Not a Get Request" output if no subsequent GET request follows (instead, Chrome sends \0 to signal its not sending anything anyway).
Note: I didn't experience any of this in the actual Postman application.
While the server waits for chrome to send a request, it cannot service any other requests. To prevent this from happening, consider using an asynchronous approach.

How to get form-data from TcpClient

I created a simple webserver that serves HTML files when you connect to it.
I created a simple form, now how come I get the form paramaters, I tried to keep reading from the request but I can't find it..
That's all I can read:
The code I use to read from the client:
while(true)
{
Console.WriteLine("Waiting for next request...");
TcpClient client = listener.AcceptTcpClient();
StreamReader sr = new StreamReader(client.GetStream());
StreamWriter sw = new StreamWriter(client.GetStream());
try
{
string req = sr.ReadLine();
for(int i = 0; i < 11; i++) {
string header = sr.ReadLine();
Console.WriteLine(header);
}
string[] toks = req.Split(' ');
Console.WriteLine("");
Console.WriteLine("Request Method: " + toks[0]);
Console.WriteLine("Request File: " + toks[1]);
Console.WriteLine("Response: " + toks[2]);
Console.WriteLine("");
string page = toks[1];
//Serving files&catch comes here...
}

UDP relay implementation do not work as I expected

I am trying to implement the relay of UDP communication.
For example, I have two terminals:
192.168.10.5
192.168.10.6
I would like to monitor between the two by way of 192.168.10.3.
My environment:
Unity 5.1.2-f1 on MacOS X 10.8.5 using C#
Following is my code snippet related to the UDP communication.
void Monitor() {
UdpClient client = new UdpClient (port);
client.Client.ReceiveTimeout = 1000; // msec
client.Client.Blocking = false;
while (ToggleComm.isOn) {
try {
IPEndPoint anyIP = new IPEndPoint(IPAddress.Any, 0);
byte[] data = client.Receive(ref anyIP);
string text = Encoding.ASCII.GetString(data);
if (text.Length == 0) {
Thread.Sleep(20);
continue;
}
string fromIP = anyIP.Address.ToString();
// send to the other
if (fromIP.Equals(ipadr1)) {
client.Send(data, data.Length, ipadr2, port);
Debug.Log("from: " + ipadr1 + " to " + ipadr2 + data);
} else {
client.Send(data, data.Length, ipadr1, port);
Debug.Log("from: " + ipadr2 + " to " + ipadr1 + data);
}
}
catch (Exception err) {
}
// without this sleep, on android, the app will freeze at Unity splash screen
Thread.Sleep(200);
}
client.Close ();
}
With the code above,
I can send from 192.168.10.5 to 192.168.10.3
I can send from 192.168.10.3 to 192.168.10.6 (relay)
I can receive at 192.168.10.3 from 192.168.10.6
I cannot receive at 192.168.10.5 from 192.168.10.3
where 192.168.10.6 works as echo server, returning received string back.
My debug print on the relay says
from: 192.168.10.5 to 192.168.10.6
from: 192.168.10.6 to 192.168.10.5
It seems that the relay (192.168.10.3) send to 192.168.10.5, but 192.168.10.5 cannot receive the relayed one.
Following code worked (not elegant yet, though).
I had misunderstanding about port of the sender and receiver.
void Monitor() {
UdpClient client = new UdpClient (port);
client.Client.ReceiveTimeout = 300; // msec
client.Client.Blocking = false;
string fromPort = "6000"; // at first 6000 is set as dummy
while (ToggleComm.isOn) {
try {
IPEndPoint anyIP = new IPEndPoint(IPAddress.Any, 0);
byte[] data = client.Receive(ref anyIP);
string text = Encoding.ASCII.GetString(data);
if (text.Length == 0) {
Thread.Sleep(20);
continue;
}
string fromIP = anyIP.Address.ToString();
// send to the other
if (fromIP.Equals(ipadr1)) {
fromPort = anyIP.Port.ToString(); // store the port
client.Send(data, data.Length, ipadr2, port);
Debug.Log("1 from: " + fromIP + "(" + fromPort
+ ") to " + ipadr2 + "(" + port.ToString() + ")");
} else {
client.Send(data, data.Length, ipadr1, Convert.ToInt32(fromPort));
Debug.Log("2 from: " + fromIP + "(" + "..."
+ ") to " + ipadr1 + "(" + fromPort + ")");
}
}
catch (Exception err) {
}
// without this sleep, on android, the app will freeze at Unity splash screen
Thread.Sleep(200);
}
client.Close ();
}
I put the unity project at github (v0.3)

C# tcp socket client downloads files from server

Currently I have this problem. Client downloads from server successfully only the 1st time. The 2nd time it doesn't work(nothing happens, no crash). Here the code from both side:
At client, in mainForm, If I click the download button, I will call a method sendComment(string request) from another class, loginForm.
At server, after receiving string request from client, server will call sendComment(string listFiles). listFiles consists of all files' names and sizes that client need to download.
The string listFiles format: "commitRequest mName usID fiName1 fiSize1 fiName2 fiSize2...".After receive this string, client will request each file in string.
Client side:
loginForm:
private void Connect()
{
try
{
serversocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
serversocket.Blocking = true;
IPHostEntry IPHost = Dns.Resolve(textBox1.Text);
string[] aliases = IPHost.Aliases;
IPAddress[] addr = IPHost.AddressList;
IPEndPoint ipepServer = new IPEndPoint(addr[0], 8090);
serversocket.Connect(ipepServer);
clientsock = serversocket;
Thread MainThread = new Thread(new ThreadStart(listenclient));
MainThread.Start();
MessageBox.Show("Connected successfully", "Infomation", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
catch (SocketException se)
{
Console.WriteLine(se.Message);
}
catch (Exception eee)
{
MessageBox.Show("Socket Connect Error.\n\n" + eee.Message + "\nPossible Cause: Server Already running. Check the tasklist for running processes", "Startup Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
Application.Exit();
}
}
void listenclient()
{
Socket sock = clientsock;
string cmd = server;
byte[] sender = System.Text.Encoding.ASCII.GetBytes("CLIENT " + cmd);
sock.Send(sender, sender.Length, 0);
while (sock != null)
{
cmd = "";
byte[] recs = new byte[32767];
int rcount = sock.Receive(recs, recs.Length, 0);
string clientmessage = System.Text.Encoding.ASCII.GetString(recs);
clientmessage = clientmessage.Substring(0, rcount);
string smk = clientmessage;
cmdList = null;
cmdList = clientmessage.Split(' ');
string execmd = cmdList[0];
sender = null;
sender = new Byte[32767];
string parm1 = "";
if (execmd == "CommitRequest")
{
for (int i = 3; i < cmdList.Length - 1; i++)
{
if (i % 2 == 1)
{
sendComment("downloadFile " + cmdList[i]); // after receiving this, server will upload the file requested
downloadMFromServer(sock, cmdList[2], cmdList[1], cmdList[i], cmdList[i + 1]);
}
}
continue;
}
}
private void downloadMFromServer(Socket s, string userID, string mName, string fileN, string fileS)
{
Socket sock = s;
string rootDir;
rootDir = #"C:\Client Data" + "\\" + userID + "\\" + mName;
Directory.CreateDirectory(rootDir);
System.IO.FileStream fout = new System.IO.FileStream(rootDir + "\\" + fileN, FileMode.Create, FileAccess.Write);
NetworkStream nfs = new NetworkStream(sock);
long size = int.Parse(fileS);
long rby = 0;
try
{
while (rby < size)
{
byte[] buffer = new byte[1024];
int i = nfs.Read(buffer, 0, buffer.Length);
fout.Write(buffer, 0, (int)i);
rby = rby + i;
}
fout.Close();
}
catch (Exception ed)
{
Console.WriteLine("A Exception occured in file transfer" + ed.ToString());
MessageBox.Show(ed.Message);
}
}
After the 1st download button click, files downloaded to client successfully, then I deleted all files downloaded, then I clicked the download button 2nd time, but this time it didn't work.
Files weren't got downloaded. I tried debugging, it didn't show any error, but the client application stopped at the step receiving the string listFiles from server. I mean client sended string re ok. server received string re ok. server sended string listFiles ok. but client didn't get listFiles. Does anyone know why it doesn't work? thanks for your help in advance.
Here is the code for the sendComment method, it's the same for both client and server app.
public void sendComment(string comment)
{
Socket serversock = serversocket;
if (serversock == null)
{
MessageBox.Show("Client not connected", "Connect Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
byte[] b = System.Text.Encoding.ASCII.GetBytes(comment + " ");
serversock.Send(b, b.Length, 0);
}
I don't upload the server side code because I don't think there's any problem with it and this post would be a bit long, but if you need just say and I will post it.
I just solved this on my own. Actually, I just build the solution instead of running debug and both server and client app work fine. The problem seems to rise only when I try debugging. Maybe it's a Visual Studio bug or there's something in my code prevent the debug.

Categories

Resources