Im connecting to a TcpClient and using StreamReader to ReadLine.
My application fetch emails every 2 seconds.
When I run my application on desktop it works fine, but if I run it as a win service it hangs on "info = _Reader.ReadLine();" before it returns the "info" to "CheckResultOK(info);" every minute.
What causes this major delay?
I have current code:
string info = "";
_Connection = new TcpClient(Host, Port);
if (!Ssl)
{
_Stream = _Connection.GetStream();
}
else
{
_Stream = new SslStream(_Connection.GetStream(), false);
((SslStream)_Stream).AuthenticateAsClient(Host);
}
_Reader = new StreamReader(_Stream, System.Text.Encoding.Default);
info = _Reader.ReadLine();
CheckResultOK(info);
Related
Zebra browser print is nice feature. I have able to print label from any browser app like Chrome, Firefox or even from the Postman api by sending API requests. Printer is connected through USB.
My problem is that I can not able to print the same from any windows app (Wpf/Winform). I have tried the TCP IP print with this code
NetworkStream ns = null;
Socket socket = null;
try
{
string ipAddress = "127.0.0.1";
int port = 9100;
var printerIP = new IPEndPoint(IPAddress.Parse(ipAddress), port);
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket.Connect(printerIP);
ns = new NetworkStream(socket);
byte[] toSend = Encoding.ASCII.GetBytes(zpl);
ns.Write(toSend, 0, toSend.Length);
}
finally
{
if (ns != null)
ns.Close();
if (socket != null && socket.Connected)
socket.Close();
}
But it is not working.
Also tried to send data from API
var data =
"{\"device\":{\"deviceType\":\"printer\",\"uid\":\"Zebra test printer\",\"provider\":\"com.zebra.ds.webdriver.desktop.provider.DefaultDeviceProvider\",\"name\":\"Zebra test printer\",\"connection\":\"driver\",\"version\":3,\"manufacturer\":\"Zebra Technologies\"}}, \r\n\"data\":\"^XA ^FT230,45,1 ^A0N,28,28 ^FD $1.00^FS ^XZ\"";
var client = new HttpClient();
var response = client.PostAsync(new Uri("http://127.0.0.1:9100/write"), new StringContent(data)).ConfigureAwait(false).GetAwaiter().GetResult();
if (response.IsSuccessStatusCode)
{
MessageBox.Show("success");
}
var responseContent = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();
MessageBox.Show(responseContent);
However this API code is working perfectly from any browser based app or from Postman
Here is my Browser print setting
Please let me know how can I print from the windows app?
I'm creating a windows service that would communicate with another application. The problem I'm facing is that the NamedPipeServerStream closes as soon as the client disconnects. I want that the server should remain open, so whenever the client application starts, it gets connected.
I don't want to use WCF, the messages would be small, so I just want to keep it simple using Named Pipes. Multiple clients can connect to the service. Is there a way to keep the server always running?
This is what I have so far:
var server = new NamedPipeServerStream("pipeeee123");
server.SetAccessControl(pipeSa);
server.WaitForConnection();
StreamReader reader = new StreamReader(server);
StreamWriter writer = new StreamWriter(server);
while (true)
{
var line = reader.ReadLine();
this.EventLog.WriteEntry("Got command " + line, EventLogEntryType.Information);
var resp = HandleCommand(line);
writer.WriteLine(resp);
writer.Flush();
}
Take a look at this code.
var server = new NamedPipeServerStream("PipesOfPiece");
StreamReader reader = new StreamReader(server);
StreamWriter writer = new StreamWriter(server);
while (true)
{
if (!server.IsConnected)
{
try
{
server.WaitForConnection();
}
catch (IOException)
{
server.Disconnect();
continue;
}
}
var line = reader.ReadLine();
if (!server.IsConnected)
{
continue;
}
if(!string.IsNullOrEmpty(line))
{
writer.WriteLine(String.Join("", line.Reverse()));
}
writer.Flush();
}
From what I see, your server just falls because you don't correctly process reopening of connnection + edge cases.
Also, consider the fact that you can only work with once instance of a client at a time.
Named Pipe Instances are expected to terminate on client disconnect, see: https://learn.microsoft.com/en-us/windows/win32/ipc/named-pipe-instances?redirectedfrom=MSDN.
For multiple clients services, see the following project: https://www.codeproject.com/Articles/864679/Creating-a-Server-Using-Named-Pipes
Also perhaps helpful:
How to use named pipes in C# correctly -- several connections, server recreation etc
I know it's not asynchronous, but if anybody wants a synchronous version, I was able to get it working using the following:
NamedPipeServerStream server = new NamedPipeServerStream("pipeee",
PipeDirection.InOut, 10,
PipeTransmissionMode.Message,
PipeOptions.WriteThrough, 1024, 1024, pipeSecurity);
while (true)
{
// re-connect if disconnected
if (!server.IsConnected)
{
server = new NamedPipeServerStream("pipeee",
PipeDirection.InOut, 10,
PipeTransmissionMode.Message,
PipeOptions.WriteThrough, 1024, 1024, pipeSecurity);
}
server.WaitForConnection();
StreamReader reader = new StreamReader(server);
StreamWriter writer = new StreamWriter(server);
while (true)
{
var line = reader.ReadLine();
var resp = HandleCommand(line);
writer.WriteLine(resp);
writer.Flush();
// exit inner loop if disconnected, outer loop will handle re connection
if(!server.IsConnected)
{
break;
}
}
}
I want to create for each request return response in socket c# and android.
I find the relevant socket and send a request, asking for the data I need.
After sending the request, I receive bytes until it sends the response. Then I stop receiving.
My server will need to handle many clients at once, and preferably multiple requests from a client at once. I need both the client and server to be able to receive messages at any time
I wrote this code:
message = Encoding.UTF8.GetString(dataRec,0,c);
dataRec = new byte[2048];
switch(message)
{
case "list-menu":
sendListMenu();
break;
case "login":
isLogin(message);
break;
}
login method
public void isLogin(string str){
string message = "";
Model_Users users;
dataSend=Encoding.UTF8.GetBytes("send-result");
newsocket.Send(dataSend);
//newsocket.close(); if close not receive
c = newsocket.Receive(dataRec);
message = Encoding.UTF8.GetString(dataRec,0,c);
XmlSerializer xml = new XmlSerializer(typeof(Model_Users));
using (TextReader reader = new StringReader(message))
{
if (reader != null)
{
users = (Model_Users)xml.Deserialize(reader);
MessageBox.Show(users.username);
dataSend = Encoding.UTF8.GetBytes("success-login");
newsocket.Send(dataSend);
newsocket.Close();
}
}
}
android code (client):
socket = new Socket();
socketAddress = new InetSocketAddress(cursor.getString(cursor.getColumnIndex("ip")), 9999);
socket.connect(socketAddress, 10000);
bufferWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
bufferWriter.write(getrequest);
bufferWriter.flush();
String rvdMsgTxt = "";
stringBuilder = new StringBuilder();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
while ((rvdMsgTxt = bufferedReader.readLine()).equals("success-login")) {
stringBuilder.append(rvdMsgTxt);
bufferedReader.mark(100);
bufferedReader.reset();
}
bufferWriter.write(XMLConvertor.usersSerializeXML("user", "pass"));
bufferWriter.flush();
But this doesn't work.
this SOLVED by newsocket.Shutdown(SocketShutdown.Send);
I'm quite new working with sockets and I'm trying to get data from a RFID equipment that has a raw streaming on port 1000. Found this code and I got this working on a console application with this code
TcpClient tcpClient;
NetworkStream networkStream;
tcpClient = new TcpClient("10.19.1.101", 10000);
networkStream = tcpClient.GetStream();
StreamReader streamReader = new StreamReader(networkStream);
StreamWriter streamWriter = new StreamWriter(networkStream);
String wline = "";
while (wline != "exit")
{
Console.Write(streamReader.ReadLine());
Console.Write(Environment.NewLine);
Console.Write("next command:");
wline = Console.ReadLine();
streamWriter.Write(wline);
}
Obviously this code waits for some commands to be written in the remote host but I don't need to write anything. I'm just trying to get the information sent by the RFID equipment that is basically a RFID tag code. Tag codes can arrive in random periods of time. I actually commented some lines in the previous code an was able to print the tag codes as arrive in the console.
TcpClient tcpClient;
NetworkStream networkStream;
tcpClient = new TcpClient("10.19.1.101", 10000);
networkStream = tcpClient.GetStream();
StreamReader streamReader = new StreamReader(networkStream);
//StreamWriter streamWriter = new StreamWriter(networkStream);
String wline = "";
while (wline != "exit")
{
Console.Write(streamReader.ReadLine());
Console.Write(Environment.NewLine);
//Console.Write("next command:");
//wline = Console.ReadLine();
//streamWriter.Write(wline);
}
I thing is not the correct way cause I'm not controlling the while loop. Can anybody guide me to the right path or approach to solve my "problem".
EDIT: I have changed the code and looks like this:
TcpClient tcpClient = new TcpClient("10.19.1.101", 10000);
NetworkStream networkStream = tcpClient.GetStream();
StreamReader streamReader = new StreamReader(networkStream);
while (tcpClient.Connected)
{
Console.WriteLine(streamReader.ReadLine();
}
the curious thing is, when I do the same thing in a winFrom application the application freezes after a few times in the loop.
It seems you are not updating the wline to the stream values inside the loop.
I have the following code for the server application:
TcpListener recSock = new TcpListener(400);
recSock.Start();
TcpClient client = recSock.AcceptTcpClient();
NetworkStream netStream = client.GetStream();
Byte[] data = new Byte[256];
int i;
while((i = netStream.Read(data, 0, data.Length)) != 0) {
string cmd = ASCIIEncoding.ASCII.GetString(data, 0, i);
Console.WriteLine(cmd);
if(cmd == "R") {
RestartScheduler();
}
}
client.Close();
And the client looks like:
TcpClient client = new TcpClient();
client.Connect("VM-SCHEDULER", 400);
NetworkStream netStream = client.GetStream();
Byte[] data = ASCIIEncoding.ASCII.GetBytes("R");
netStream.Write(data, 0, data.Length);
netStream.Flush();
client.Close();
All is fine the first time the client connects the "R" command is read and the RestartScheduler() method is called, however all subsequent commands fail until the server is restarted.
I have used telnet to connect to the server after the first attempt and it is still listening on the port.
Where am i going wrong?
EDIT:
Basically what I am trying to accomplish is that the server will listen always, a client will then connect send the "R" command then close the connection. The client must be able to connect to the server at any time to issue the command. There will only be 1 client at any given time.
If there is no data to be read, netStream.Read will return 0 and your while loop will exit, disconnecting the client at client.Close();. You have nothing in your code to allow the server to continue receiving in this scenario.
You need to keep listening for connections until the application is shutdown, so put the listen and GetStream in a while loop. Since Stream.Read is a blocking call, you should have some data for the data reading while loop (unless timeout occurs). Otherwise it will close the connection and go back to listening for a new one.
Note: I've not included any error handling in here, you'll need to add that yourself.
TcpListener recSock = new TcpListener(400);
recSock.Start();
while (!stopping)
{
TcpClient client = recSock.AcceptTcpClient();
NetworkStream netStream = client.GetStream();
Byte[] data = new Byte[256];
int i = netStream.Read(data, 0, data.Length);
while(i != 0)
{
string cmd = ASCIIEncoding.ASCII.GetString(data, 0, i);
Console.WriteLine(cmd);
if(cmd == "R") {
RestartScheduler();
}
i = stream.Read(bytes, 0, bytes.Length);
}
client.Close();
Thread.Sleep(1); // Will allow the stopping bool to be updated
}
Module level add:
private bool stopping = false;
In your shutdown function:
stopping = true;
Are you connecting multiple times, or sending multiple commands down the same connection? If you could provide a short but complete program to demonstrate the problem, that would really help.
My guess is that you're running into problems due to reading multiple commands from a single connection in one go, but it's hard to know without more information. Don't forget that a single call to Write from the client can easily result in multiple reads at the server end - or vice versa.
Well the server will exit after the first command it receives, no?
At the least, you're missing using statements:
TcpListener recSock = new TcpListener(IPAddress.Loopback, 400);
recSock.Start();
using (TcpClient client = recSock.AcceptTcpClient())
{
using (NetworkStream netStream = client.GetStream())
{
Byte[] data = new Byte[256];
int i;
while ((i = netStream.Read(data, 0, data.Length)) != 0)
{
string cmd = Encoding.ASCII.GetString(data, 0, i);
Console.WriteLine(cmd);
if (cmd == "R")
{
RestartScheduler();
}
}
}
client.Close();
}
and
using (TcpClient client = new TcpClient())
{
client.Connect("VM-SCHEDULER", 400);
using (NetworkStream netStream = client.GetStream())
{
Byte[] data = Encoding.ASCII.GetBytes("R");
netStream.Write(data, 0, data.Length);
netStream.Flush();
}
client.Close();
}