I have a client-server type application with the server running HttpListener and the client uploading data to the server using WebClient.UploadData. The code works quite well (whith large data buffers 60K and up) except one installation where UploadData times out when data buffer size is bigger that 16384. Here is my code on the client:
internal bool UploadData(byte[] buffer, String file, String folder)
{
try
{
String uri = "http://" + GlobalData.ServerIP + ":" + GlobalData.ServerHttpPort + "/upload:";
NameValueCollection headers = new NameValueCollection();
headers.Set("Content-Type", "application/octet-stream");
headers.Set("Y-Folder", folder);
headers.Set("Y-File", file);
using (WebClient wc = new WebClient())
{
wc.Credentials = new NetworkCredential(WebUserName, WebPassword);
wc.Headers.Add(headers);
wc.UploadData(new Uri(uri), buffer);
return true;
}
}
catch (Exception ex)
{
GlobalData.ODS("Exception in UploadFile " + ex.Message);
return false;
}
}
On the server
ODS(TraceDetailLevel.Level4, "Process upload ");
HttpListenerResponse response = e.RequestContext.Response;
String disp = "";
String fil = "";
String folder = "";
Stream body = e.RequestContext.Request.InputStream;
long len64 = e.RequestContext.Request.ContentLength64;
Encoding encoding = e.RequestContext.Request.ContentEncoding;
ODS(TraceDetailLevel.Level4, "Process upload " + len64 + " bytes encoding " + encoding.EncodingName);
NameValueCollection nvp = e.RequestContext.Request.Headers;
try
{
disp = nvp["Content-Disposition"];
fil = nvp["Y-File"];
folder = nvp["Y-Folder"];
}
catch { }
BinaryReader reader = new BinaryReader(body, encoding);
byte[] data = new byte[len64];
long total = 0;
while (true)
{
int dataleft = data.Length - (int)total;
int offset = (int)total;
GlobalData.ODS("Reading binary stream offset=" + offset + " read dataleft=" + dataleft);
int cnt = reader.Read(data, offset, dataleft);
if (cnt <= 0)
{
break;
}
total += cnt;
if (len64 <= total)
{
break;
}
}
ODS(TraceDetailLevel.Level4, "Process upload: Got data "+total+" should have="+len64);
if (total == len64)
{
//process data
The code above works well on all but one installation. What is wrong?
It looks like I found the source of the problem. This one installation in question that fails my code has AVG Free Antivirus installed on a computer that runs my HTTP server code. If I disable AVG on that computer my code works. Wondering if anybody runs into similar issues with AVG.
Related
I am creating a software to help the user to create his own http server. But the site isn't loading if he uses his own input. I tried to use this:
private void startListeningForConnection()
{
while (true)
{
DateTime time = DateTime.Now;
String data = "";
byte[] bytes = new byte[2048];
Socket client = httpServer.Accept(); // Blocking Statement
// Reading the inbound connection data
while (true)
{
int numBytes = client.Receive(bytes);
data += Encoding.ASCII.GetString(bytes, 0, numBytes);
if (data.IndexOf("\r\n") > -1)
break;
}
// Data Read
serverLogsText.Invoke((MethodInvoker)delegate
{
// Runs inside the UI Thread
serverLogsText.Text += "\r\n\r\n";
serverLogsText.Text += data;
serverLogsText.Text += "\n\n------ End of Request -------";
});
// Send back the Response
String resHeader = "HTTP/1.1 200 Everything is Fine\nServer: Vedoo_Server\nContent-Type: text/html; charset: UTF-8\n\n";
String resBody =
"<!DOCTYPE>" +
"<html>" +
" <head>" +
" <title>" + svtitletext.Texts + "</title>" +
" </head>" +
" <body>" +
servercontent.Text +
" </body>" +
"</html>";
String resStr = resHeader + resBody;
byte[] resData = Encoding.ASCII.GetBytes(resStr);
client.SendTo(resData, client.RemoteEndPoint);
client.Close();
}
Where servercontent is a richtextbox that allows the user to input his html code. For example<h4>Hello\<\\h4\>\
I was expecting that on the localhost to show user imput. The custom pagetitle works.
So im working on a .raw file uploader made in C# winform, and its working fine but any files a little bit above 2GB don't upload to the server.
Im using the RestSharp library, heres the upload function
private void uploadfile(string filelocation)
{
output.AppendText(Environment.NewLine + DateTime.Now + $" Start Uploading {filelocation}");
string newfilelocation;
if (nocopy.Checked) {
newfilelocation = filelocation;
}
else
{
newfilelocation = Path.GetDirectoryName(filelocation) + #"\temp\" + Path.GetFileName(filelocation);
//check if a temp patch exits, create one if not.
string temppath = Path.GetDirectoryName(filelocation) + #"\temp\";
bool exists = System.IO.Directory.Exists(temppath);
if (!exists)
System.IO.Directory.CreateDirectory(temppath);
if (File.Exists(newfilelocation))
{
File.Delete(newfilelocation);
}
try //for somereason, copy file fails sometimes...
{
File.Copy(filelocation, newfilelocation, true);
}
catch
{
output.AppendText(Environment.NewLine + DateTime.Now + $" {newfilelocation} uploading failed once will try again");
System.Threading.Thread.Sleep(30000);
try //2nd try
{
File.Copy(filelocation, newfilelocation, true);
}
catch
{
output.AppendText(Environment.NewLine + DateTime.Now + $" {newfilelocation} uploading failed second time");
return;
}
// Todo: Additional recovery here,
// like telling the calling code to re-open the file selection dialog
}
}
var client = new RestClient(txtserver.Text);
client.Timeout = 30 * 60 * 1000;// 1000 ms = 1s, 30 min = 30*60*1000
client.Authenticator = new HttpBasicAuthenticator(txtusername.Text, txtpassword.Text);
if (!File.Exists(newfilelocation))
{
MessageBox.Show("Please check file location");
return;
}
var request = new RestRequest();
request.Method = Method.POST;
request.AddHeader("Accept", "application/json");
request.Parameters.Clear();
request.AddHeader("Content-Type", "multipart/form-data");
if(String.IsNullOrEmpty(txtsamplename.Text))
{
request.AddParameter("run_name", Path.GetFileNameWithoutExtension(newfilelocation));
}
else
{
request.AddParameter("run_name", txtsamplename.Text);
}
request.AddParameter("project_name", txtprojectname.Text);
request.AddParameter("run_desc", txtdescription.Text);
request.AddParameter("qc_tool", qctool.SelectedIndex);
request.AddParameter("temp_data", TempData.Checked);
request.AddFile("rawfile", newfilelocation);
request.ReadWriteTimeout = 2147483647;
request.Timeout = 2147483647;
var response = client.Execute(request);
output.AppendText(Environment.NewLine + response.Content);
output.AppendText(Environment.NewLine + DateTime.Now + $" {newfilelocation} uploaded");
if (!nocopy.Checked)
{
File.Delete(newfilelocation);
}
}
Wondering what solutions there could be so i can upload larger files. The server isnt the issue, since the files can be uploaded to the server using a browser extension. Its on the winform app side.
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();
}
}
}
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.
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.