android aQuery post send images to server C# - c#

Im trying to send several images from android client to C# server via http post with AQuery library.
urlport="http://192.168.100.139:1111";
Map<String, Object> params = new HashMap<>();
params.put("testimage", new File(getRealPathFromURI(imageUris.get(0))) );
aQuery
.ajax(urlport,params,JSONObject.class,new AjaxCallback<JSONObject>(){
#Override
public void callback(String url, JSONObject json, AjaxStatus status){
alert("post complete");//not working
}
});
C# HTTP Listener
lstnr = new Server();
lstnr.url = "http://" + ipbox.Text;
lstnr.port = portfield.Text;
lstnr.Received += Server_Received_multipart;
lstnr.StartListen();
in Server.class I set delegate that runs in receiving loop, accepts Stream
class Server{
......
public event EventHandler<Stream> Received = delegate { };
......
public void Start(){
string prefix = String.Format("{0}:{1}/", url, port);
listener.Prefixes.Add(prefix);
if (!listener.IsListening) {
listener.Start();
isListening = true;
try
{
while (isListening)
{
HttpListenerContext context = listener.GetContext();
HttpListenerRequest request = context.Request;
Stream postdata = request.InputStream;
Received(this, postdata);
}
}
catch (Exception e)
{
MessageBox.Show("Start() error: " + e.Message);
}
}
}
}
private void Server_Received_multipart(object sender, Stream msg)
{
Dispatcher.Invoke((Action)(() =>
{
//here want to handle stream and show images in window and save on disk
MessageBox.Show("message received"); //this not working too
}));
}
Before I made a fork where server accepts string with imagees in it encoded in base64/ works fine, but app crashes woth OurOfMemory error if send several images with size>3-4 Mb. Sorry if grammatic not good, Im russian

Related

C#/.NET app using SimpleHttpServer not returning a response to browser?

NOTE: This is not a Python app, it is C#.
I have created a C# app I am trying to make into a simple server using this simple C# module I found on the web:
https://gist.github.com/aksakalli/9191056
I have everything wired up, but when I access my server from a browser, it never receives a response. I checked this by using the Network tab in the Chrome debugger. I see the request being made, but the Response sub-panel is always empty.
I traced my server code and it runs without error, but after adding the headers to the response and closing the output stream, nothing happens on the browser side. Below are the relevants part of my code. Can anyone tell me why my browser is never seeing a response and how I can fix this?
public delegate Task<string> ProcessHttpContext(HttpListenerContext context);
private ProcessHttpContext _processHttpContextFunc = null;
public SimpleHTTPServer(string path, int port, ProcessHttpContext processHttpContextFunc)
{
this.Initialize(path, port);
this._processHttpContextFunc = processHttpContextFunc;
}
public SimpleHTTPServer(string path)
{
//get an empty port
TcpListener l = new TcpListener(IPAddress.Loopback, 0);
l.Start();
int port = ((IPEndPoint)l.LocalEndpoint).Port;
l.Stop();
this.Initialize(path, port);
}
public void Stop()
{
_serverThread.Abort();
_listener.Stop();
}
private void Listen()
{
_listener = new HttpListener();
_listener.Prefixes.Add("http://+:" + _port.ToString() + "/main-page/");
_listener.Start();
while (true)
{
try
{
HttpListenerContext context = _listener.GetContext();
Process(context);
}
catch (Exception ex)
{
Debug.WriteLine("Exception occurred during GetContext() call: " + ex.Message);
if (ex.InnerException != null)
Debug.WriteLine(" Inner Exception: " + ex.InnerException.Message);
}
}
}
async private void Process(HttpListenerContext context)
{
if (context == null)
throw new ArgumentNullException("The context parameter is empty.");
try
{
// Call it with the current context.
string strResult = await this._processHttpContextFunc(context);
byte[] bytes = System.Text.Encoding.UTF8.GetBytes(strResult);
context.Response.AddHeader("Content-Type", "text/plain; charset=UTF-8");
context.Response.AddHeader("Content-Length", strResult.Length.ToString());
context.Response.SendChunked = false;
context.Response.StatusCode = (int)HttpStatusCode.OK;
context.Response.StatusDescription = "OK";
context.Response.OutputStream.Write(bytes, 0, bytes.Length);
context.Response.OutputStream.Flush();
}
}
catch (Exception ex)
{
context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
}
context.Response.OutputStream.Close();
}
private void Initialize(string path, int port)
{
this._rootDirectory = path;
this._port = port;
_serverThread = new Thread(this.Listen);
_serverThread.Start();
}

Send data from service to server (400) Bad Request

I have create 1 service and the purpose of this service is to get value from hardware and send to the server (MVC,Controller) and display the value.
The value sometime able to send to server but sometime show this error msg.
THIS ERROR MSG GET FROM SERVICE
13/8/2019 5:35:37 PM : The remote server returned an error: (400) Bad
Request.. at System.Net.WebClient.UploadDataInternal(Uri address,
String method, Byte[] data, WebRequest& request) at
System.Net.WebClient.UploadString(Uri address, String method, String
data) at IndicatorReadingService.Service1.Start()
I don't know what mistake that i have make.Hope you guys can helped me solved this problem thank you in advance.
protected override void OnStart(string[] args)
{
string sInterval = ConfigurationManager.AppSettings["Interval"];
int iInterval;
if(Int32.TryParse(sInterval,out iInterval))
{
iInterval = Int32.Parse(sInterval);
}
else
{
iInterval = 700;
}
timer.Interval = iInterval;
timer.Elapsed += new ElapsedEventHandler(this.OnElapsedTime);
timer.Enabled = true;
CreateLogFile(DateTime.Now.ToString() + " : Start Service.");
}
//POST
private void Start()
{
data = "NULL";
try
{
data = new Indicator().StartRead();
//var vm = new { reading = temp};
using (var client = new WebClient())
{
client.Headers.Add(HttpRequestHeader.ContentType, "application/json");
client.Encoding = Encoding.UTF8;
client.UploadString(new Uri(ConfigurationManager.AppSettings["APIUrl"] + data), "POST");
}
}
catch (Exception ex)
{
using (var client = new WebClient())
{
client.Headers.Add(HttpRequestHeader.ContentType, "application/json");
client.Encoding = Encoding.UTF8;
client.UploadString(new Uri(ConfigurationManager.AppSettings["APIUrl"] + ex.Message), "POST");
}
CreateLogFile(DateTime.Now.ToString() + " : " + ex.Message+"."+ex.StackTrace);
}
}
client.UploadString is expecting the first parameter to be the URL you are wanting to send it to, and the second to be the data. You should change your code to be:
client.UploadString(ConfigurationManager.AppSettings["APIUrl"], data);

Can a NetMQ router socket (server) detect if a req socket (client) has reached a timeout?

I am using NetMQ v3.3.3.4 to develop a simple server(RouterSocket) - client(RequestSocket) scenario. It works as expected except for one thing.
Sometimes the server takes too long to return a response and the client reaches a timeout. This behavior is desired. The issue here is that the server does not detect that the client is already gone and it continues processing the request. At some point the processing is done and the server tries to return a response. The server never realizes that the client is not listening anymore and thinks that a response has been successfully delivered. This leads to a misleading user feedback and wrong log file entries.
Is it possible for the server to detect if a client is still waiting for a response?
Server
private void Listen()
{
using (var poller = new NetMQPoller())
using (var responseSocket = new RouterSocket())
using (var poisonedSocket = new ResponseSocket())
{
responseSocket.Bind(_bindServerString);
poisonedSocket.Bind(_bindTerminationString);
var keepAliveTimer = new NetMQTimer(KeepAliveInterval);
keepAliveTimer.Elapsed += (s, a) =>
{
_monitorPublisher.Status["KeepAlive"] = Application.LocalDateTime.Now.ToString();
_monitorPublisher.SendStatus();
};
poisonedSocket.ReceiveReady += (s, a) =>
{
a.Socket.ReceiveFrameBytes();
poller.Stop();
};
responseSocket.ReceiveReady += (s, a) =>
{
try
{
bool header = true;
byte[] response = null;
while (a.Socket.TryReceiveFrameBytes(out byte[] message))
{
// Using a ROUTER socket...
if (header)
{
// We have to first, wait for the first frame,
// which is the address (header) of the REQ socket.
// Afterwards, we have to wait for the second frame,
// which is 0 and act as a delimiter between the REQ address
// and the actual body of the request.
a.Socket.SendFrame(message, true);
// Once we have the header delimiter, we can be sure that
// the next frame is the actual request.
header = !(message.Length == 0);
}
else
{
// Parse the request and return a response
BridgeRequestReceived?.Invoke(message, out response);
a.Socket.SendFrame(response);
}
}
}
catch (Exception e)
{
Logger.Instance.Log(e);
}
};
poller.Add(keepAliveTimer);
poller.Add(responseSocket);
poller.Add(poisonedSocket);
Logger.Instance.Log($"Receiving requests on: {_bindServerString}", Application.LogCategory.Info);
poller.Run();
responseSocket.Close();
poisonedSocket.Close();
}
}
Client
private string SendRequest(IBridgeMessage request, out Exception e)
{
e = null;
string response = null;
using (var socket = new RequestSocket())
{
try
{
socket.Connect(_endpoint);
byte[] encryptedRequest = CryptoAES.StandardCrypto.Encrypt(Encoding.UTF8.GetBytes(NMTBridgeMessageFactory.Serialize(request)));
socket.SendFrame(encryptedRequest);
if (socket.TryReceiveFrameBytes(_timeout, out byte[] reply))
{
response = Encoding.UTF8.GetString(CryptoAES.StandardCrypto.Decrypt(reply));
}
else
{
e = new TimeoutException("Timeout occured!");
response = null;
}
}
catch (Exception ex)
{
e = ex;
response = null;
}
}
return response;
}
I expect the server detects a client disconnection.

C# WebSockets On Windows 7 with OWIN

I am trying to use WebSockets on Windows 7. I trying to use System.Net.Sockets, I have tried following these examples, but each of them has one problem or another running on Windows 7:
WebSocket Server in C# ,Writing a WebSocket server in C# ,
Creating a “Hello World” WebSocket example , How to implement an asynchronous socket in C#, MULTI-THREADED TCP SERVER IN C# ,Paul Batum
I have looked into several 3rd party tools, but it looks like they are either no longer supported or in beta.
Here's the code I have so far:
public class WebSocketService {
private TcpListener _listener;
private TcpClient _tcpClient;
public event Action<NetworkStream> OnLoadData;
public WebSocketService() {
Listen();
}
public void Listen(int port) {
_listener = new TcpListener(IPAddress.Parse("127.0.0.1"), port);
_listener.Start();
_listener.BeginAcceptTcpClient(HandleAsyncConnection, null);
}
private void HandleAsyncConnection(IAsyncResult result)
{
try
{
_tcpClient = _listener.EndAcceptTcpClient(result);
_tcpClient.NoDelay = true;
NetworkStream stream = _tcpClient.GetStream();
// extract the connection details and use those details to build a connection
ConnectionDetails connectionDetails = GetConnectionDetails(stream, _tcpClient);
PerformHandshake(stream, connectionDetails.Header);
if (connectionDetails.Path.Equals("/myApiPath"))
{
OnLoadData?.Invoke(stream);
}
}
catch (Exception ex)
{
//write ex to log
throw;
}
}
private static ConnectionDetails GetConnectionDetails(NetworkStream stream, TcpClient tcpClient)
{
// read the header and check that it is a GET request
string header = HttpHelper.ReadHttpHeader(stream);
var getRegex = new Regex(#"^GET(.*)HTTP\/1\.1", RegexOptions.IgnoreCase);
Match getRegexMatch = getRegex.Match(header);
if (getRegexMatch.Success)
{
// extract the path attribute from the first line of the header
string path = getRegexMatch.Groups[1].Value.Trim();
// check if this is a web socket upgrade request
var webSocketUpgradeRegex = new Regex("Upgrade: websocket", RegexOptions.IgnoreCase);
Match webSocketUpgradeRegexMatch = webSocketUpgradeRegex.Match(header);
if (webSocketUpgradeRegexMatch.Success)
{
return new ConnectionDetails(stream, tcpClient, path, ConnectionType.WebSocket, header);
}
return new ConnectionDetails(stream, tcpClient, path, ConnectionType.Http, header);
}
return new ConnectionDetails(stream, tcpClient, string.Empty, ConnectionType.Unknown, header);
}
private void PerformHandshake(Stream stream, string header)
{
try
{
Regex webSocketKeyRegex = new Regex("Sec-WebSocket-Key: (.*)");
Regex webSocketVersionRegex = new Regex("Sec-WebSocket-Version: (.*)");
// check the version. Support version 13 and above
const int webSocketVersion = 13;
int secWebSocketVersion = Convert.ToInt32(webSocketVersionRegex.Match(header).Groups[1].Value.Trim());
if (secWebSocketVersion < webSocketVersion)
{
//throw some exception
}
string secWebSocketKey = webSocketKeyRegex.Match(header).Groups[1].Value.Trim();
string setWebSocketAccept = ComputeSocketAcceptString(secWebSocketKey);
var newLine = "\r\n";
string response = ("HTTP/1.1 101 Switching Protocols" + newLine
+ "Connection: Upgrade" + newLine
+ "Upgrade: websocket" + newLine
+ "Sec-WebSocket-Accept: " + setWebSocketAccept + newLine + newLine);
WriteHttpHeader(response, stream);
}
catch (Exception ex)
{
// Write Log Entry(ex);
WriteHttpHeader("HTTP/1.1 400 Bad Request", stream);
throw;
}
}
}
When the OnLoadData event fires it calls another class which simply has:
var jsonSerializerSettings = new JsonSerializerSettings
{
ContractResolver = new CamelCasePropertyNamesContractResolver()
};
var message = JsonConvert.SerializeObject(someData, jsonSerializerSettings);
var messageData = Encoding.UTF8.GetBytes(message);
_clientStream.Write(messageData, 0, messageData.Length);
_clientStream.Flush();
I then get this error:
An established connection was aborted by the software in your host
machine at System.Net.Sockets.Socket.Send(Byte[] buffer, Int32
offset, Int32 size, SocketFlags socketFlags) at
System.Net.Sockets.NetworkStream.Write(Byte[] buffer, Int32 offset,
Int32 size)
NativeErrorCode 10053 int
SocketErrorCode ConnectionAborted System.Net.Sockets.SocketError
I am looking for a simple C# WebSockets implementation that works on Windows 7. I cannot use SignalR or ASP.NET because I am using OWIN to self-host Web API.
I took a look at this post, but I can't figure out how the OP made it work.
Anyone know how to do this?

Reading and saving post data

I have been assigned to take over someones position, however I do not really know C#. There is a server (192.268. something ect) that will post data to a site (unknown site, lets say bleh.com)
This is what the posting code snippet looks like:
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(
"https://server-ip-here/postlistener?filename=filename.zlib");
req.UseNagleAlgorithm = true;
req.AllowWriteStreamBuffering = true;
req.Method = "POST";
req.Accept = "application/xml";
req.ServicePoint.Expect100Continue = false;
System.Net.ServicePointManager.CheckCertificateRevocationList = false;
req.Proxy = new WebProxy();
filename = "filename.dat";
byte[] postData = File.ReadAllBytes(filename);
Stream stream = req.GetRequestStream();
stream.Write(postData, 0, postData.Length);
stream.Flush();
stream.Close();
req.BeginGetResponse(new AsyncCallback(responseHandler), this);
Which I beleive I get the post request in this form
www.blah.com/upload?filename=file_1234_12389126495129847980.zlib
I am unsure how to listen for post requests and then get the data from them and save them as a file.
Currently I have tried this:
private void Form1_Load(object sender, EventArgs e)
{
listener = new HttpListener();
// listener.Prefixes.Add("http://localhost:8000/");
listener.Prefixes.Add("http://127.0.0.1:8000/");
listener.AuthenticationSchemes = AuthenticationSchemes.Anonymous;
listener.Start();
listenThread1 = new Thread(new ParameterizedThreadStart(startlistener));
listenThread1.Start();
}
private void startlistener(object s)
{
while (true)
{
// blocks until a client has connected to the server
ProcessRequest();
}
}
private void ProcessRequest()
{
var result = listener.BeginGetContext(ListenerCallback, listener);
result.AsyncWaitHandle.WaitOne();
}
private void ListenerCallback(IAsyncResult result)
{
var context = listener.EndGetContext(result);
Thread.Sleep(1000);
var data_text = new StreamReader(
context.Request.InputStream,
context.Request.ContentEncoding).ReadToEnd();
var cleaned_data = System.Web.HttpUtility.UrlDecode(data_text);
context.Response.StatusCode = 200;
context.Response.StatusDescription = "OK";
MessageBox.Show(cleaned_data);
context.Response.Close();
}
Which listens on the local host (Would sub local host for the website once we establish what it will be).
Not sure how to grab the post though, right now I can only listen for it. Ideally I would only like to accept posts from a specific IP address also.
Any ideas how I can go about grabbing the post data (which will be binary) and saving it as a file?

Categories