WebClient doesn't connect to IHttpHandler - c#

I made my program according to example 1 that was made for .NET framework 2, but I converted it to .NET framework 3.5. How should I modify this code to make it working? How can I debug server side? Server side seems to work when I manually insert parameters to url, so problem must be in client side code.
private void UploadFile(string fileName, System.IO.Stream data)
{
UriBuilder ub = new UriBuilder("http://localhost:59491/receiver.ashx");
ub.Query = string.Format("filename={0}", fileName);
WebClient c = new WebClient();
c.OpenWriteCompleted += (sender, e) =>
{
PushData(data, e.Result);
e.Result.Close();
data.Close();
};
c.OpenWriteAsync(ub.Uri);
}
private void PushData(System.IO.Stream input, System.IO.Stream output)
{
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = input.Read(buffer, 0, buffer.Length)) != 0)
{
output.Write(buffer, 0, bytesRead);
}
}
1 http://www.c-sharpcorner.com/UploadFile/nipuntomar/FileUploadsilverlight03182009030537AM/FileUploadsilverlight.aspx

My initial take is the port specifier. On that sample, he has the request URI specifically set to port 3840, but he never shows modifying settings to force the web server to use that port when hosting the handler. make sure that the request URI is using the same port that you do when accessing the handler manually from a browser.
EDIT: I think this must be it, I just recreated the sample in a new project in VS2008 using the newest frameworks and everything works correctly, once I get the port set right.
As for debugging the server, if you're hosting the server half of the project out of visual studio (which you would be if you follow that guy on CSharpCorner sample), you should already be debugging the server component, just put a breakpoint in the server codebehind.

Related

wss WebSocket server in Mono C# : SslStream gives me no data but Stream do

Since days I'm trying to get (JS)wss/(c#)SslStream connection to work in order to create a wss server in mono c#.
My Problem : When an incomming secure WebSocket connection is accepted by the server, I can't get data from it in order to begin the handshake process.
What I did so far :
I setup a TCPListener that accept the client giving me a TCPClient instance.
I get the stream from the TCPClient and create a SslStream from it.
I synchronously authenticate it with AuthenticateAsServer(X509Certificate2)
I unsuccessfully try to read data
Other details :
I note that if I use a Stream object instead of an SslStream one, I succed in getting data from it (but crypted as expected)
I tested to connect my WebSoket to same adress/port to Fleck (built on my box with Monodevelop too) using the same pfx certificate and got it working properly
I note also that Fleck throw messages saying it recieve 0 byte, then it close the connection and (in some way) reconnect it and get data properly from Socket/SslStream.
I don't get any error, SslStream seem to be correctly authenticated
I correctly connect clients in https and deal with requests on an another port in the same program
My Configuration :
OS : ArchLinux
C# : Mono .Net Framework 4.7
Browsers (Chromium & Firefox)
Despite of all my research so far I've not found the solution , maybe someone can help me to wonder what I miss here ...
Thanks in advance for any help !
The listen code :
public void AudioListen ()
{
audioComListener.Start ();
while (isAudioActive) {
TcpClient s = audioComListener.AcceptTcpClient ();
Stream clientStream;
string hellostr;
clientStream = getClientStream(s);
if(debugCommuncation)
{
logToFileLine("(KEY) HandShaking begins with "+s.Client.RemoteEndPoint.ToString ().Split (':') [0]);
}
if(!WebSocketHandshake(clientStream))
{
if(debugCommuncation)
{
logToFileLine("(KEY) (X) HandShake read 0 byte from "+s.Client.RemoteEndPoint.ToString ().Split (':') [0]);
}
s.Close();
return;
}
else
{
logToFileLine("(KEY) HandShaking OK with "+s.Client.RemoteEndPoint.ToString ().Split (':') [0]);
}
hellostr=streamReadLine(clientStream);
if(hellostr.IndexOf("hello:")==0)
{
string usrstr=hellostr.Split(':')[1];
User usr= Users.GetUser(usrstr);
if(usr!=null)
{
usr.TcpC=s;
User usrdest=usr.corresp;
if( usrdest!=null &&
usrdest.ByPass==null &&
usrdest.TcpC!=null)
{
Stream clientStream2 = getClientStream(usrdest.TcpC);
usr.ByPass=new TCPByPass(clientStream,clientStream2);
usrdest.ByPass=usr.ByPass;
}
}
}
Thread.Sleep (1);
};
}
Function to get the SslStream :
private Stream getClientStream(TcpClient s,bool forceHTTP=false)
{
Stream clientStream;
if(isSSL && !forceHTTP)
{
clientStream = new SslStream (s.GetStream ());
((SslStream)clientStream).AuthenticateAsServer(SrvCert);
// Set timeouts for the read and write to 5 seconds.
/**/clientStream.ReadTimeout = 5000;
clientStream.WriteTimeout = 5000;
//SecuDiag.MakeAllDiag(((SslStream)clientStream));
}
else
{
clientStream=s.GetStream ();
}
return clientStream;
}
Function that try to get data for hanshake purpose :
public bool WebSocketHandshake(Stream clientStream)
{
string hellostr;
// Here I test trying to get data (Also tried to use Stream.ReadByte())
Byte[] toto=new Byte[2048];
((SslStream)clientStream).Read(toto,0,2048);
if(toto[0]==0)return false;
Console.WriteLine("#############################################");
Console.WriteLine("toto array is {0} bytes long",toto.Length);
for(int t =0;t<10;t++)
{
for(int u =0;u<10;u++)
{
Console.Write(toto[t*10+u].ToString());
}
Console.WriteLine(";");
}
Console.WriteLine("#############################################");
// Trying to get data
//hellostr=streamReadLine(clientStream);
//Console.WriteLine(hellostr);
return true;
}
I think I solved the problem. I don't understand why, but I think its necessary to close the accepted connection just after accepting it iaoi the connection is wss. The the websocket wil automagically reconnect :)

Can't send large data from Android through TCP socket

I'm trying to send an array of bytes from android (client) to Linux (server), I can send around 17kB but then the socket send an client socket timeout exception. At the server side I'm using netcat with the next command:
nc -l -p 55000 > out.txt
This works ok because I'm capable of sending files from other computer, for this reason I think the problem is at the client side (Android).
I'm using Visual Studio 2015 with Xamarin to compile the project and I tried many methods to send thought socket with the same result, between 15~20kB sended. Of course the permissions on Android to send through internet and other rights are ok.
This is the first mode I tried:
byte[] data = new byte[200000];
TcpClient client = new TcpClient("192.168.0.245", 55000);
client.SendBufferSize = 8192;
NetworkStream ns = client.GetStream();
ns.ReadTimeout = 1000;
ns.WriteTimeout = 1000;
ns.Write(data, 0, data.Length);
ns.Flush();
ns.Close();
client.Close();
With this method only around 17kB are received and the socket is not closed, but the close methods are executed (I tested it with the debugger placing MessageBox to test in release).
Other method I've tested is this:
IPEndPoint remoteEP = new IPEndPoint(IPAddress.Parse("192.168.0.245"), 55000);
System.Net.Sockets.Socket sender = new System.Net.Sockets.Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
sender.ExclusiveAddressUse = true;
sender.LingerState = new LingerOption(true, 1);
sender.NoDelay = true;
sender.SendBufferSize = 8192;
sender.ReceiveBufferSize = 8192;
sender.SendTimeout = 1000;
sender.ReceiveTimeout = 1000;
sender.Ttl = 42;
try{
byte[] data = new byte[200000];
sender.Connect(remoteEP);
for (int a = 0; a < data.Length;)
{
int len = (data.Length - a) > 8192 ? 8192 : data.Length - a;
a += sender.Send(data, a, len, SocketFlags.None);
}
}
catch (Exception e)
{
string a = e.ToString();
}
The program send the first 8192 bytes and in the second round an socket timeout exception is trowed. If I try to send all the bytes is one time the program executes the send method the returned bytes are the total length of the array, this mean all bytes are sent to the socket but only received 17kB.
I've tested other methods to do the same thing with the same results in two phones. The android version for compiler I'm using is 4.2. For VS and Xamarin the latest.
Also I tried to download an app from the market to send files throught TCP to see if the problem is in Netcat, firewalls, SO or other and the files was sended ok.... I'm very frustated, I think I'm doing well all the things.
Thanks in advance

Proxy Socket Managing

I'm trying to create a transparent proxy with c#. i was able to transfer my network traffic into my proxy client and redirect it to my proxy server. it's working, but i have 2 problems,
1- It's slow, max speed is 60kbps, here is how i transfer traffic between my server and proxy client
while (SocketConnected(tcp_link.Client) &&
SocketConnected(_tcp.Client) &&
!ioError)
{
try
{
Thread.Sleep(1);
if (streamLink.DataAvailable)
{
byte[] l_buffer = new byte[4096];
int l_read = streamLink.Read(l_buffer, 0, l_buffer.Length);
byte[] l_data = new byte[l_read];
Array.Copy(l_buffer, l_data, l_data.Length);
byte[] l_send = MBR.reverse(l_data);
_stream.Write(l_send, 0, l_send.Length);
}
if (_stream.DataAvailable)
{
byte[] c_buffer = new byte[4596];
int c_read = _stream.Read(c_buffer, 0, c_buffer.Length);
byte[] c_data = new byte[c_read];
Array.Copy(c_buffer, c_data, c_data.Length);
byte[] c_send = MBR.reverse(c_data);
streamLink.Write(c_send, 0, c_send.Length);
}
}
catch (Exception ex)
{
onErrorLog(this, new ErrorLogEventArgs(ex));
ioError = true;
}
}
my other question is: when should i close my socket? and which one should get closed first? is http server going to close connection with my proxy server or i should disconnect?
sorry for my back english
I think it's not a problem with mere logic but rather about handling the parallelism. I have used SocketAsyncEventArgs for implementing a high performance, async TCP server and it shines.
A good article can be found here.

c# Socket Closing

I'm working on a http proxy application, everything is working fine (client can connect to server and get contents), the problem is neither of HTTP Server or browser close the TCP connection.. I'm not sure if I'm doing it right, here is the code:
while (tcp_link.Connected && _tcp.Connected && !ioError)
{
try
{
Thread.Sleep(100);
if (streamLink.DataAvailable)
{
byte[] l_buffer = new byte[10000];
int l_read = streamLink.Read(l_buffer, 0, l_buffer.Length);
byte[] l_data = new byte[l_read];
Array.Copy(l_buffer, l_data, l_data.Length);
_stream.Write(l_data, 0, l_data.Length);
}
if (_stream.DataAvailable)
{
byte[] c_buffer = new byte[10500];
int c_read = _stream.Read(c_buffer, 0, c_buffer.Length);
byte[] c_data = new byte[c_read];
Array.Copy(c_buffer, c_data, c_data.Length);
streamLink.Write(c_data, 0, c_data.Length);
}
}
catch
{
ioError = true;
}
}
I have same code both sides (proxy client, and proxy server)
NOTE: browser will connect to proxy client (which is on the same computer), and proxy client will connect to proxy server, and obviously proxy server will connect to http server, the reason is i wan't to encode data before sending it out
How long have you observed the connection open for?
It's very likely that the client uses HTTP 1.1 where Persistent Connections are on by default.
If you're writing a proxy then you should consider: http://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html
Okay i found the problem, who ever is out there having problem with closing socket connection..
Actually, Socket.Available isn't working as i expected, to see if a socket is really connected you should check both Available and Poll properties, below function should resolve your problem: thanks to: zendar
bool SocketConnected(Socket s)
{
bool part1 = s.Poll(1000, SelectMode.SelectRead);
bool part2 = (s.Available == 0);
if (part1 & part2)
return false;
else
return true;
}
i hope this solve your problem too ;)

Strange but true - Works fine manually but fails in automated tool like QTP

I have windows file import method and applciation works fine if i click buttons manually but same code fails if i run my application using tools like QTP (Quick Test Professional)
I have highlighted failing line in bold. [ remoteStream.Write(buffer, 0, bytesRead);]
using (FileStream localStream = File.OpenRead(filePath))
{
RemoteFile remoteFile = this.serverComponent.GetUploadFileHandle(filePath);
if (remoteFile == null)
{
stopWatch.Stop();
}
using (RemoteFileStream remoteStream = new RemoteFileStream(remoteFile))
{
long localFileSize = localStream.Length;
long readSoFar = 0;
int bytesRead = 0;
byte[] buffer = new byte[bufferSize];
while ((bytesRead = localStream.Read(buffer, 0, bufferSize)) > 0)
{
remoteStream.Write(buffer, 0, bytesRead);
readSoFar += bytesRead;
progressListener.UpdateFileProgress(firmwareID, readSoFar, localFileSize);
}
}
uploadSuccess = this.server.UploadFileDone(remoteFile);
}
stopWatch.Stop();
progressListener.UpdateFileStatus(firmwareID, uploadSuccess ? FirmwareImportStatus.ImportSuccessful : FirmwareImportStatus.ImportFailed);
}
QTP code which triggers the import.
SwfWindow("Swfname:=ImportFWImagesWF").SwfButton("Swfname:=btnNext","text:=Import").Click
I am overriding Stream c# class. and I am ending up having Socket exceptions
"System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host"
I am overriding Stream c# class. My class name is RemoteFileStream
Server Code
public override void Write(byte[] buffer, int offset, int count)
{
#region Check Args
if (buffer == null)
{
throw (new ArgumentNullException("The buffer is null"));
}
if (offset < 0 || count < 0)
{
throw (new ArgumentOutOfRangeException("The offset or count is negative."));
}
if (offset + count > buffer.Length)
{
throw (new ArgumentException("The sum of offset and count is larger than the buffer length."));
}
#endregion
_rf.Write(buffer, offset, count);//Exception comes from here
}
NOTE: Exception rises only when I access my application from QTP tool. If I manually run my application there is no issues. Is it because of permission issue? Please help me.
When QTP runs steps it has the option of using simulating events in the application (in .NET's case firing .NET event) or simulating device actions. The way to tell which option QTP is using for a click step can be to see if the mouse cursor moved to the button when the step took place.
If QTP is using event run then it could be that it didn't run the exact events that the application is expecting thus giving different results than during manual testing. In this case you can try using the DeviceReplay object (as described here).

Categories

Resources