.NET network socket print on Zebra EPL/ZPL - c#

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

Related

How can I send multiple string messages from client to server using a single instance of TcpClient?

I have separate client and server console apps. I'm simply trying to send a string from the client to the server and have the server write the string to the console using TcpClient. I can send a single message just fine but when I throw a while loop into the client app to try and send multiple messages without closing the TcpClient, the server doesn't write anything to the console.
//Server
using (TcpClient client = listener.AcceptTcpClient())
{
NetworkStream ns = client.GetStream();
byte[] buffer = new byte[1024];
while (true)
{
if (ns.DataAvailable)
{
int bytesRead = 0;
string dataReceived = "";
do
{
bytesRead = ns.Read(buffer, 0, buffer.Length);
dataReceived += Encoding.UTF8.GetString(buffer, 0, bytesRead);
}
while (bytesRead > 0);
Console.WriteLine($"Message:{ dataReceived }\n");
}
}
}
//Client
using (TcpClient client = new TcpClient(hostname, port))
{
if (client.Connected)
{
Console.WriteLine("Connected to server");
NetworkStream ns = client.GetStream();
string message = "";
//Removing this while loop I can send a single message that the server will write to console
//but with the loop present the server does not write anything
while (true)
{
message = Console.ReadLine();
byte[] messageBytes = UTF8Encoding.UTF8.GetBytes(message);
ns.Write(messageBytes);
Console.WriteLine($"Message Sent! ({ messageBytes.Length } bytes)");
}
}
}
I'm interested in learning sockets and have been pouring over SO questions and MSDN docs for two days but cannot figure out why it's not working as I intend. I feel a bit silly even submitting a question because I'm sure it's something basic I'm not understanding. Could someone please drop some knowledge on me?
SOLUTION
//Server
using (TcpClient client = listener.AcceptTcpClient())
{
NetworkStream ns = client.GetStream();
StreamReader sr = new StreamReader(ns);
string message = "";
while (true)
{
message = sr.ReadLine();
Console.WriteLine(message);
}
}
//Client
using (TcpClient client = new TcpClient(hostname, port))
{
if (client.Connected)
{
Console.WriteLine("Connected to server");
NetworkStream ns = client.GetStream();
StreamWriter sw = new StreamWriter(ns) {Autoflush = true};
string message = "";
while (true)
{
message = Console.ReadLine();
sw.WriteLine(message);
}
}
}
If you debug your server, you'll see that it does receive data. You're just not displaying the data, because the only output your server does is after the loop when the byte count returned is 0: Console.WriteLine($"Message:{ dataReceived }\n");. The byte count will only be 0 when the underlying socket has been shutdown. That never happens because your client is stuck in an infinite loop.
A better approach, for a simple text-based client/server example like this, is to use StreamWriter and StreamReader with line-based messages, i.e. WriteLine() and ReadLine(). Then the line breaks serve as the message delimited, and your server can write the message each time it receives a new line.
Note also that in your example above, you are assuming that each chunk of data contains only complete characters. But you're using UTF8 where characters can be two or more bytes, and TCP doesn't guarantee how bytes that are sent are grouped. Using StreamWriter and StreamReader will fix this bug too, but if you wanted to do it explicitly yourself, you can use the Decoder class, which will buffer partial characters.
For some examples of how to correctly implement a simple client/server network program like that, see posts like these:
.NET Simple chat server example
C# multithreading chat server, handle disconnect
C# TcpClient: Send serialized objects using separators?

Sending String over TCP/IP uisng C#

I have a robotic system that can be interacted with over TCP/IP. I have been able to control the system in Matlab using the following code:
AT = tcpip('cim-up',8000);
fopen(AT);
fprintf(AT, '$global[1] = 33');
I need to emulate the same command in C#. I have tried the following code:
// Connect to Robot using TCPIP
string IP = "cim-up";
TcpClient tcpclnt = new TcpClient();
Console.WriteLine("Connecting.....");
try
{
tcpclnt.Connect(IP, 8000);
Console.WriteLine("Connected");
}
catch
{
Console.WriteLine("Failed");
}
StreamWriter AT_writer = new StreamWriter(tcpclnt.GetStream(), Encoding.ASCII);
AT_writer.Write("$global[1]=33");
This code will connect to the TCP/IP address but the server does not respond to the $global[1]=33 command.
I have also tried the following:
Byte[] data = System.Text.Encoding.ASCII.GetBytes("$global[1]=33");
// Get a client stream for reading and writing.
NetworkStream stream = tcpclnt.GetStream();
// Send the message to the connected TcpServer.
stream.Write(data, 0, data.Length);
Does anyone have any suggestions as I have a successful Matlab implementation?
Thanks

Sending raw ZPL to Zebra printer via PrintServer is not working

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

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 ...
}

Categories

Resources