Print label on Zebra browser printer - c#

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?

Related

How to get network printer status using C# socket?

I have an ASP .NET Web API and network printer(Epson TM-U220). I need to get the printer status on the Epson code and I just try as below. But I've only got printer-ready status. When the status is like printer busy, out of paper, door open, and others then the socket is waiting and API is crashed. Not get any response such a situation.
var server = "<Printer IP Address>";
Socket clientSocket = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
clientSocket.NoDelay = true;
IPAddress ip = IPAddress.Parse(server);
IPEndPoint ipep = new IPEndPoint(ip, 9100);
clientSocket.Connect(ipep);
var command = "" + (char)27 + (char)97 + (char)14; //Epson command to get printer status
byte[] commandBytes = Encoding.ASCII.GetBytes(command);
clientSocket.Send(commandBytes );
var statusCode = clientSocket.Receive(commandBytes );
clientSocket.Close();
If the Printer is ready, statusCode got 3. Not getting any other codes.

How to send and receive commands from a UDP network server via .NET Core console application

I have a UDP server, which is a scale, that is connected to the network. It is listening to any data being sent to it and response with a data back to the client, depending on what command is sent to it. I was able to test this with YAT, a software used to test serial communication.
Testing UDP Connection on YAT:
I want to create a C# (.NET Core) console application that does the same thing. Basically, I want to connect to the UDP server (scale), send commands to it, and receive the data from it. But it doesn't seem to work at the receiving end.
static void Main(string[] args)
{
var ipAddress = "10.130.12.81";
var portNumber = 2102;
var ipEndPoint = new IPEndPoint(IPAddress.Parse(ipAddress), portNumber);
try
{
var client = new UdpClient();
client.Connect(ipEndPoint);
if (client != null)
{
var weigh = "\nW\r";
var data = Encoding.ASCII.GetBytes(weigh);
client.Send(data, data.Length);
var receivedData = client.Receive(ref ipEndPoint);
Console.WriteLine($"Received Data: {receivedData}");
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
When I run the code, it is able to connect and send the data, but sits idle at the client.Receive line, waiting for a message to be sent.
The second time around, I created 2 console apps:
Sender
static void Main(string[] args)
{
var udpClient = new UdpClient();
var ipEndPoint = new IPEndPoint(IPAddress.Parse(_ipAddress), _port);
udpClient.Connect(ipEndPoint);
var msgSent = Encoding.ASCII.GetBytes("W\n");
udpClient.Send(msgSent, msgSent.Length);
}
Receiver
static void Main(string[] args)
{
var udpServer = new UdpClient(2102);
var ipEndPoint = new IPEndPoint(IPAddress.Any, _port);
var msgReceived = udpServer.Receive(ref ipEndPoint);
Console.Write("received data from: " + ipEndPoint.ToString());
}
I tried to run and send messages several times, but no luck. Not sure if I am missing anything. I'll keep hammering away at this; if this doesn't work I'll try using the Socket class instead of UdpClient.

For each request return response in socket C#

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);

How to send a message and receive a response on the same socket

I have the following code that sends a multicast message then waits for a response to be sent to the address the message came from. If I watch the traffic in Wireshark I can see the message sends ok and a response comes back to the correct IP and port however the socket never returns from the receive line, it's like the response is not being picked up.
var multicastAddress = IPAddress.Parse("239.255.255.250");
var multicastPort = 1900;
var unicastPort = 1901;
using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp))
{
socket.Bind(new IPEndPoint(IPAddress.Any, unicastPort));
socket.Connect(new IPEndPoint(multicastAddress, multicastPort));
var thd = new Thread(() =>
{
try
{
while (true)
{
var response = new byte[8000];
EndPoint ep = new IPEndPoint(IPAddress.Any, unicastPort);
socket.ReceiveFrom(response, ref ep);
var str = Encoding.UTF8.GetString(response);
Devices.Add(new SsdpDevice() {Location = str});
}
}
catch
{
//TODO handle exception for when connection closes
}
});
socket.Send(broadcastMessage, 0, broadcastMessage.Length, SocketFlags.None);
thd.Start();
Thread.Sleep(30000);
socket.Close();
}
I know I should be using the asynchronous methods on the socket class and need stop relying on Thread.Sleep but I just want to get a simple example working before I tidy up the code.
Gavin, check this out:
Don't use different ports. How do you expect to multicast on one and receive on another?
Don't use Connect(), multicast is connectionless messaging (just as broadcast is).
Set socket option to multicast after Bind().
Use SendTo() instead of Send(), which won't work in this case.
First start receiving (even in blocking mode, it's a different endpoint), then send.
And a simple working example:
var broadcastMessage = Encoding.UTF8.GetBytes("Hello multicast!");
var multicastAddress = IPAddress.Parse("239.255.255.250");
var signal = new ManualResetEvent(false);
var multicastPort = 1900;
using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp))
{
var multicastEp = new IPEndPoint(multicastAddress, multicastPort);
EndPoint localEp = new IPEndPoint(IPAddress.Any, multicastPort);
// Might want to set this:
//socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, 1);
socket.Bind(localEp);
socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(multicastAddress, IPAddress.Any));
// May want to set this:
//socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastTimeToLive, 0); // only LAN
var thd = new Thread(() =>
{
var response = new byte[8000];
socket.ReceiveFrom(response, ref localEp);
var str = Encoding.UTF8.GetString(response).TrimEnd('\0');
Console.WriteLine("[RECV] {0}", str);
signal.Set();
Console.WriteLine("Receiver terminating...");
});
signal.Reset();
thd.Start();
socket.SendTo(broadcastMessage, 0, broadcastMessage.Length, SocketFlags.None, multicastEp);
Console.WriteLine("[SEND] {0}", Encoding.UTF8.GetString(broadcastMessage));
signal.WaitOne();
Console.WriteLine("Multicaster terminating...");
socket.Close();
Console.WriteLine("Press any key.");
Console.ReadKey();
}

How to use Tor control protocol in C#?

I'm trying to send commands to the Tor control port programmatically to make it refresh the chain. I haven't been able to find any examples in C#, and my solution's not working. The request times out. I have the service running, and I can see it listening on the control port.
public string Refresh()
{
TcpClient client = new TcpClient("localhost", 9051);
string response = string.Empty;
string authenticate = MakeTcpRequest("AUTHENTICATE\r\n", client);
if (authenticate.Equals("250"))
{
response = MakeTcpRequest("SIGNAL NEWNYM\r\n", client);
}
client.Close();
return response;
}
public string MakeTcpRequest(string message, TcpClient client)
{
client.ReceiveTimeout = 20000;
client.SendTimeout = 20000;
string proxyResponse = string.Empty;
try
{
// Send message
StreamWriter streamWriter = new StreamWriter(client.GetStream());
streamWriter.Write(message);
streamWriter.Flush();
// Read response
StreamReader streamReader = new StreamReader(client.GetStream());
proxyResponse = streamReader.ReadToEnd();
}
catch (Exception ex)
{
// Ignore
}
return proxyResponse;
}
Can anyone spot what I'm doing wrong?
Edit:
Following Hans's suggestion, which he has now deleted for some reason, I tried to send "AUTHENTICATE\n" instead of just "AUTHENTICATE". Now I'm getting back an error from Tor: "551 Invalid quoted string. You need to put the password in double quotes." At least there's some progress.
I then tried to send "AUTHENTICATE \"\"\n", like it wants to, but it times out while waiting for a response.
Edit:
The command works fine in the Windows Telnet client. I don't even have to add the quotes. Can't figure out what's wrong. Maybe the double quotes aren't encoded correctly when they're sent?
public static void CheckIfBlocked(ref HtmlDocument htmlDoc, string ypURL, HtmlWeb hw)
{
if (htmlDoc.DocumentNode.InnerText.Contains("FORBIDDEN ACCESS!"))
{
Console.WriteLine("Getting Blocked");
Utils.RefreshTor();
htmlDoc = hw.Load(ypURL, "127.0.0.1", 8118, null, null);
if (htmlDoc.DocumentNode.InnerText.Contains("FORBIDDEN ACCESS!"))
{
Console.WriteLine("Getting Blocked");
Utils.RefreshTor();
}
}
}
public static void RefreshTor()
{
IPEndPoint ip = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 9051);
Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
try
{
server.Connect(ip);
}
catch (SocketException e)
{
Console.WriteLine("Unable to connect to server.");
RefreshTor();
return;
}
server.Send(Encoding.ASCII.GetBytes("AUTHENTICATE \"butt\"\n"));
byte[] data = new byte[1024];
int receivedDataLength = server.Receive(data);
string stringData = Encoding.ASCII.GetString(data, 0, receivedDataLength);
if (stringData.Contains("250"))
{
server.Send(Encoding.ASCII.GetBytes("SIGNAL NEWNYM\r\n"));
data = new byte[1024];
receivedDataLength = server.Receive(data);
stringData = Encoding.ASCII.GetString(data, 0, receivedDataLength);
if (!stringData.Contains("250"))
{
Console.WriteLine("Unable to signal new user to server.");
server.Shutdown(SocketShutdown.Both);
server.Close();
RefreshTor();
}
}
else
{
Console.WriteLine("Unable to authenticate to server.");
server.Shutdown(SocketShutdown.Both);
server.Close();
RefreshTor();
}
server.Shutdown(SocketShutdown.Both);
server.Close();
}
When I send the AUTHENTICATE command, the StreamReader is reading the response to the end, but there is no end because on success the stream is kept open. So I changed it to only read the first line of the response in this case.
public static string MakeTcpRequest(string message, TcpClient client, bool readToEnd)
{
client.ReceiveTimeout = 20000;
client.SendTimeout = 20000;
string proxyResponse = string.Empty;
try
{
// Send message
using (StreamWriter streamWriter = new StreamWriter(client.GetStream()))
{
streamWriter.Write(message);
streamWriter.Flush();
}
// Read response
using (StreamReader streamReader = new StreamReader(client.GetStream()))
{
proxyResponse = readToEnd ? streamReader.ReadToEnd() : streamReader.ReadLine();
}
}
catch (Exception ex)
{
throw ex;
}
return proxyResponse;
}
Added another example I'm using myself below. Also added steps for those who would like to setup Tor that can accept commands through the control port.
Socket server = null;
//Authenticate using control password
IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 9151);
server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
server.Connect(endPoint);
server.Send(Encoding.ASCII.GetBytes("AUTHENTICATE \"your_password\"" + Environment.NewLine));
byte[] data = new byte[1024];
int receivedDataLength = server.Receive(data);
string stringData = Encoding.ASCII.GetString(data, 0, receivedDataLength);
//Request a new Identity
server.Send(Encoding.ASCII.GetBytes("SIGNAL NEWNYM" + Environment.NewLine));
data = new byte[1024];
receivedDataLength = server.Receive(data);
stringData = Encoding.ASCII.GetString(data, 0, receivedDataLength);
if (!stringData.Contains("250"))
{
Console.WriteLine("Unable to signal new user to server.");
server.Shutdown(SocketShutdown.Both);
server.Close();
}
else
{
Console.WriteLine("SIGNAL NEWNYM sent successfully");
}
Steps to configure Tor:
Copy torrc-defaults into the directory in which tor.exe is. Default directory if you are using Tor browser is: "~\Tor Browser\Browser\TorBrowser\Data\Tor"
Open a cmd prompt window
chdir to the directory where tor.exe is. Default directory if you are using Tor browser is: "~\Tor Browser\Browser\TorBrowser\Tor\"
Generate a password for Tor control port access. tor.exe --hash-password “your_password_without_hyphens” | more
Add your password password hash to torrc-defaults under ControlPort 9151. It should look something like this: hashedControlPassword 16:3B7DA467B1C0D550602211995AE8D9352BF942AB04110B2552324B2507. If you accept your password to be "password" you can copy the string above.
You can now access Tor control via Telnet once it is started. Now the code can run, just edit the path to where your Tor files are located in the program.
Test modifying Tor via Telnet:
Start tor with the following command: tor.exe -f .\torrc-defaults
Open up another cmd prompt and type: telnet localhost 9151
If all goes well you should see a completely black screen. Type "autenticate “your_password_with_hyphens”" If all goes well you should see "250 OK".
Type "SIGNAL NEWNYM" and you will get a new route, ergo new IP. If all goes well you should see "250 OK".
Type "setevents circ" (circuit events) to enable console output
Type "getinfo circuit-status" to see current circuits
Probably you using Vidalia that generates a hashed password for control port access. You need to use Tor console app and configure a torrc file.

Categories