Sending raw ZPL to Zebra printer via PrintServer is not working - c#

Problem
I am trying to send zpl RAW to print server. There is a Zebra ZM400 printer.
I could get PrintServer, PrintQueue objects. Also, I could add a job, and write to its JobStream.
I checked print queue (on Windows), and the document was sent. The printer data light blinks for 1/2 seconds.
Progress
Here is my code for print to print server:
PrintServer ps = new PrintServer(#"\\192.168.1.1");
PrintQueue pq = ps.GetPrintQueue("Printer 01");
Byte[] myByteBuffer = Encoding.ASCII.GetBytes(
#"^XA^MMP^PW300^LS0^LT0^FT10,60^APN,30,30^FH\^FDSAMPLE TEXT^FS^XZ");
PrintSystemJobInfo psji = pq.AddJob();
psji.JobStream.Write(myByteBuffer, 0, myByteBuffer.Length);
psji.JobStream.Flush();
psji.JobStream.Close();
Issue
When I check print queue (on Windows), the document has 0 bytes. And then, the printer prints nothing.
Do I missing some special char? Or, do I send wrong raw data?

In my application I use the following code which works fine:
ZPLString = #"^XA^MMP^PW300^LS0^LT0^FT10,60^APN,30,30^FH\^FDSAMPLE TEXT^FS^XZ";
// Open connection
System.Net.Sockets.TcpClient client = new System.Net.Sockets.TcpClient();
client.Connect("10.10.5.85", 9100);
// Write ZPL String to connection
System.IO.StreamWriter writer = new System.IO.StreamWriter(client.GetStream());
writer.Write(ZPLString);
writer.Flush();
// Close Connection
writer.Close();
client.Close();
edit: *port 6101 is the default for Zebra printers, 9100 is the alternate port

Combining the OP's question and Johan's answer gives you a valid document using PrintServer:
LocalPrintServer localPrintServer = new LocalPrintServer();
// List the print server's queues
PrintQueue pq = localPrintServer.GetPrintQueue(#"Boca FGL 200 DPI");
PrintSystemJobInfo job = pq.AddJob();
System.IO.StreamWriter writer = new System.IO.StreamWriter(job.JobStream);
writer.Write(#"hello world<p>");
writer.Flush();

Related

Reading and writing on and from named pipe

I'm trying out IPC with named pipes in a test application that I wrote for that purpose. I want to read a value from a pipe, but the reader doesn't seem to read anything.
I'm starting a server process and a client. The server uses a named pipe called InitPipe to tell the client a name for a new pipe for communication. After that happens, a new server process and the client get connected to the new pipe, the other server process and client get disconnected and the InitPipe reopened for new processes to communicate with the server.
The client writes data to the pipe and the new server process should read the data. That's where the problem is. The server doesn't seem to get the values off the pipe.
private void svr_task(string comPipe)
{
var server = new NamedPipeServerStream(comPipe);
write("Com-Pipe: " + comPipe); //'write' just writes to a TextBox on the UI thread
server.WaitForConnection();
write("Client connected: " + comPipe);
StreamReader reader = new StreamReader(server);
StreamWriter writer = new StreamWriter(server);
while (server.IsConnected)
{
var line = reader.ReadLine(); //the program doesn't seem to run past this line
write(line);
}
write("Client disconnected: " + comPipe);
server.Dispose();
write("Com-Pipe closed: " + comPipe);
}
private void cl_start()
{
//This is for InitPipe
var clientInit = new NamedPipeClientStream("InitPipe");
NamedPipeClientStream client = new NamedPipeClientStream("InitPipe");
clientInit.Connect();
Dispatcher.Invoke(() => stat_cl1.Content = "Initialize...");
StreamReader reader = new StreamReader(clientInit);
StreamWriter writer = new StreamWriter(clientInit);
while (clientInit.IsConnected)
{
var line = reader.ReadLine();
client = new NamedPipeClientStream(line);
clientInit.Dispose();
}
//This is where the communication with the server thread starts
client.Connect();
Dispatcher.Invoke(() => stat_cl1.Content = "Connected");
reader = new StreamReader(client);
writer = new StreamWriter(client);
while (client.IsConnected)
{
string line = Dispatcher.Invoke(() => box_cl1.Text); //read a value from a textbox (This works)
writer.Write(line);
writer.Flush();
}
client.Dispose();
Dispatcher.Invoke(() => stat_cl1.Content = "Not connected");
}
I want the server thread to receive the values from the client thread. The UI thread is not locked so that I can start another client, which can also connect to a server thread.
When debugging in VS and stepping through the code, it just runs after var line = reader.ReadLine(); and seems to never get to the next line. So that's why I think it can't read any values from the pipe. But what do I need to change? I want to output the value with write.
I ran into a similar problem. It has to do with how namedpipes work. You can either be writing to or reading from a named pipe at a time. try not attaching StreamReader and StreamWriter to the stream at the same time. I got around this by a reader stream and a writer stream separate. Also, you can use the same pipe name for multiple clients, you just have to create a new instance of server after a client connects.

c# tcpclient program writing to stream but client not receiving data

I have written a TCPClient program to run on my PC. It first initiates a TCP listener to listen on a specific port then reads/writes from/to multiple TCP clients on multiple threads.
I am able to read from the client but whenever I try to send data to it, the program displays that it has sent the data, but the client does not receive anything.
Here's the code:
TcpClient client = listener.AcceptTcpClient();
var childSocketThread = new Thread(() =>
{
if (client.Connected)
{
using (NetworkStream stream = client.GetStream())
{
Console.WriteLine("connected");
byte[] data = new byte[1000];
try
{
if (stream.CanRead)
{
stream.Read(data, 0, 1000);
string dataStr = Encoding.ASCII.GetString(data);
string dataa = dataStr.TrimEnd('\0');
//Console.WriteLine(dataa);
if (dataa.Length > 10)
{
deviceid = ParseRequest(dataa);
byte[] sendnow = Encoding.ASCII.GetBytes(reply[deviceid]);
Array.Clear(data, 0, 1000);
Console.WriteLine("Recieved data: " + dataa);
Console.WriteLine("Sending data");
using (StreamWriter writer = new StreamWriter(stream))
{
writer.AutoFlush = true;
writer.WriteLine(reply[deviceid]);
}
Console.WriteLine(reply[deviceid]);
Console.WriteLine("Sent");
}
Console.WriteLine();
}
}
catch (Exception es)
{
Console.WriteLine(es);
}
}
}
});
childSocketThread.Start();
The server device that I am using is a PLC. Also, things I have already tried:
1) sending directly using Socket.Send method.
2) sending directly using NetworkStream method.
3) accepting the TCP connection as sockets. (Socket device = listener.AcceptSocket).
None of these methods seem to send to the device, even though the program tells me that it had no issues sending data since it displays "Sent" after attempting to send data.
I downloaded another program from this link http://www.codeproject.com/Articles/488668/Csharp-TCP-Server. The test app they provide with it is able to send and receive data on the same port as my program running on the same PC.
I haven't been able to get any direction on how to diagnose and more importantly solve this issue. Any ideas?
Update 2015-08-10 11:18 a.m.:
Output of the Program is as follows:
Update 2015-08-10 11:32 a.m.:
Output of Syslog Console:
Update 2015-08-10 12:07 p.m.:
Output of Wireshark:
We need you to post both sides code. Nevertheless, here is some code that works just fine, you can use it to see if you are doing something wrong.
http://www.codeproject.com/Articles/1415/Introduction-to-TCP-client-server-in-C

Read variables of a message that is sent by a server using socket

I am working on Passenger information system PIS(Train).So trains send their location to my server PIS using socket on port 8080 .So i should get their locations and show them to passengers . The message that comes from the trains has a template that i should follow that. As you can see here :
So as you can see here we have 6 variables .every integer is 4 byte. The first variable is(4 byte) message source and etc.
In my server i have to detect these variable but i don't know how can i detect them from the message .
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);
while (true)
{
TimeTableRepository objTimeTableRepository = new TimeTableRepository();
SensorRepository objSensorRepository = new SensorRepository();
ArrivalTimeRepository objArrivalTimeRepository=new ArrivalTimeRepository();
TrainRepository objTrainRepository = new TrainRepository();
// OnlineTrainRepository ObjOnlineTrainrepository = new OnlineTrainRepository();
//-----
string theString = streamReader.ReadLine();
}
}
}
Here is my listener to port 8080 and theString is the message that is send by trains.My problem is how can i detect this parameters (Message source,message destination and etc) from theString?I mean i need the value of them to store in database .
best regards
Looks like you don't need to detect anything and definitely should not be slapping this in a string to try and parse.
You already know you are getting a bunch of integers back. You even know what order they are in. Use a BinaryReader to get you your numbers and proceed from there. Once you load your reader up, it should be as simple as calling BinaryReader.ReadInt32() to read the message's numbers one after another.
I must also highly recommend you to look into using statements for your streams.
using (var reader = new BinaryReader(networkStream))
{
var messageSource = reader.ReadInt32();
var messageDestination = reader.ReadInt32();
... and so on ...
}

using python to send an image over TCP to c# server

I am working on a project that uses a python script to send an image taken with a webcam to a c# webserver using sockets. I am currently sending strings to the server from the python client using code like:
info = bytearray("Text to send", "UTF-8")
socket.send(info)
to send data to the c# server and it functions perfectly for text and numbers. I run into an issue when trying to encode the data read from the .bmp into "UTF-8", as trying this returns an error of not being able to encode certain characters into UTF-8.
I was wondering if anyone had any idea of a way to encode this that c# will be able to recognize, or, if there is a better way of trying to implement this process, I am all ears.
A couple of options I have come up with would be to 1 - use something like google drive to save the image to, or an FTP server and then have the c# server retrieve it from there or 2 - create a packet system containing the RGB values and recreating the image from those pixel values on the server.
Thanks for your help.
EDIT: I have tried sending the file this way
data = bytearray("123456789","UTF-8")
file = open("image.bmp", "rb")
data += file.read()
socket.send(data)
and was able to successfully retreive the string "123456789", but the data after this is garbage. I have also implemented sending the size of the file before sending the data and that size number is retrieved fine, but the img data saves as a black bmp.
Edit 2 :
Here is the server and client code I am using to try and recreate the image using a memory stream. I the client code is using the process mentioned by hcalves.
Client
if __name__ == "__main__":
sock = socket.socket()
sock.connect(("localhost", 50839))
with open("image.bmp", "rb") as fd:
buf = fd.read(1024)
while (buf):
sock.send(buf)
buf = fd.read(1024)
sock.close()
Server
Socket client = server.AcceptSocket();
NetworkStream stream = new NetworkStream(client);
byte[] imgData = new byte[1024];
MemoryStream memstream = new MemoryStream();
stream.Read(imgData,0, 1024);
int counter = 0;
while (stream.DataAvailable)
{
memstream.Write(imgData, 0, 1024);
stream.Read(imgData, 0, 1024);
counter = counter + 1024;
}
memstream.Seek(0, SeekOrigin.Begin);
using (Stream file = File.OpenWrite("img.bmp"))
{
byte[] buffer = new byte[8*1024];
int len;
while ((len = memstream.Read(buffer, 0, buffer.Length)) > 0)
{
file.Write(buffer,0,len);
}
}
You shouldn't need more than this recipe:
import socket
if __name__ == "__main__":
sock = socket.socket()
sock.connect(("localhost", 50839))
with open("data.bin", "rb") as fd:
buf = fd.read(1024)
while (buf):
sock.send(buf)
buf = fd.read(1024)
sock.close()
For practical reasons, you can treat str objects (the result of fd.read) as raw data, you don't need any further crazy encoding. Just iterate the file and send over the socket. Test by running this server which just echoes to stdout with python server.py > data2.bin:
import socket
import sys
if __name__ == "__main__":
sock = socket.socket()
sock.bind(("localhost", 50839))
sock.listen(1)
client, address = sock.accept()
buf = client.recv(1024)
while (buf):
sys.stdout.write(buf)
buf = client.recv(1024)
client.close()
sock.close()
A checksum shows the binary data is sent correctly:
% md5 data.bin data2.bin
MD5 (data.bin) = 8b3280072275badf3e53a6f7aae0b8be
MD5 (data2.bin) = 8b3280072275badf3e53a6f7aae0b8be
Your C# server should be able to accept this data as is. If it doesn't work, it's because your server is expecting something in particular, not just raw data.

.NET network socket print on Zebra EPL/ZPL

I need to print on network Zebra printer. From some reasons, I cannot use winspool printing ( http://support.microsoft.com/kb/154078 ), I have to print print directly through sockets on IP and port. Here is my print method:
System.Net.Sockets.TcpClient zebraClient = new System.Net.Sockets.TcpClient();
try
{
zebraClient.SendTimeout = 5000;
zebraClient.Connect(IP, port);
}
catch (Exception ex)
{
Utils.ShowError(ex);
}
if (zebraClient.Connected)
{
NetworkStream nStream;
nStream = zebraClient.GetStream();
StreamWriter wStream;
using (nStream)
{
wStream = new StreamWriter(nStream);
using (wStream)
{
wStream.Write(content);
wStream.Flush();
}
}
zebraClient.Close();
}
Problem is, that from time to time "No connection could be created, because target computer actively refused it" exception occurs. I have no idea why is that happening (maybe full printer buffer - and if so, how can I check it in both languages?). So I ask if anybody have had this problem and how can I fix it?
Try port 9100. And make sure you can see the printers IP on the network.
Heres my VB code for this.
Private Sub sendData(ByVal zpl As String)
Dim ns As System.Net.Sockets.NetworkStream = Nothing
Dim socket As System.Net.Sockets.Socket = Nothing
Dim printerIP As Net.IPEndPoint = Nothing
Dim toSend As Byte()
Try
If printerIP Is Nothing Then
'set the IP address
printerIP = New Net.IPEndPoint(IPAddress.Parse(IP_ADDRESS), 9100)
End If
'Create a TCP socket
socket = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
'Connect to the printer based on the IP address
socket.Connect(printerIP)
'create a new network stream based on the socket connection
ns = New NetworkStream(socket)
'convert the zpl command to a byte array
toSend = System.Text.Encoding.ASCII.GetBytes(zpl)
'send the zpl byte array over the networkstream to the connected printer
ns.Write(toSend, 0, toSend.Length)
Catch ex As Exception
MessageBox.Show(ex.Message, "Cable Printer", MessageBoxButtons.OKCancel, MessageBoxIcon.Error)
Finally
'close the networkstream and then the socket
If Not ns Is Nothing Then
ns.Close()
End If
If Not socket Is Nothing Then
socket.Close()
End If
End Try
End Sub
AND
Private Function createString() As String
Dim command As String
command = "^XA"
command += "^LH20,25"
If rdoSmall.Checked = True Then
command += "^FO1,30^A0,N,25,25^FD"
ElseIf rdoNormal.Checked = True Then
command += "^FO1,30^A0,N,35,35^FD"
Else
command += "^FO1,30^A0,N,50,50^FD"
End If
command += txtInput.Text
command += "^FS"
command += "^XZ"
Return command
End Function
This is just for printing out text to a s4m printer.
I'm not sure if this would apply to you, but I ran into a similar problem using asp classic. I needed to print directly to a zebra printer without changing the default printer, so what I did as a solution was create a java executable that uses sockets to connect to the zebra printer. Once I had the java executable able to send a string of Zpl to the zebra printer through a stream on the open sockets I created a batch file to run my java executable. Since the executable needed a string from my asp page, I added a user input variable to the batch file. I placed these 2 files(the java jar and .bat file) on a shared drive and using ActiveX on the asp page, I was able to send raw bytes in the form of a string directly to my zebra printer. If you have any questions don't hesitate to ask. Below is a link that will help with implementing a way to socket print to a zebra printer through java.
https://km.zebra.com/kb/index?page=content&id=SO7149&actp=RSS
This worked for me:
using System.IO;
using System.Net;
using System.Net.Sockets;
.
.
.
private void btnPrint_Click(object sender, EventArgs e) {
try {
string ipAddress = txtIPAddr.Text.ToString(); ; //ie: 10.0.0.91
int port = int.Parse(txtPort.Text.ToString()); //ie: 9100
System.Net.Sockets.TcpClient client = new System.Net.Sockets.TcpClient();
client.Connect(ipAddress, port);
StreamReader reader = new StreamReader(txtFilename.Text.ToString()); //ie: C:\\Apps\\test.txt
StreamWriter writer = new StreamWriter(client.GetStream());
string testFile = reader.ReadToEnd();
reader.Close();
writer.Write(testFile);
writer.WriteLine("Hello World!");
writer.Flush();
writer.Close();
client.Close();
}
catch (Exception ex) {
MessageBox.Show(ex.Message, "Error");
}
}

Categories

Resources