TCP client stream - stream

I'm comunicationg with a email gateway. That gateway has an specific ip and port.
The requests the gateway are JSON formated and the gateway normally responds first whith an proceeding state and then with a confirmation or error state, represented also in JSON.
The code to make the requests and receive the response is:
using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Collections.Generic;
using System.Threading;
using Microsoft.Win32;
public class TcpClientSample
{
public static void SendMessage(TcpClient client, string msg)
{
Console.WriteLine("REQUEST:" + msg);
NetworkStream stream = client.GetStream();
byte[] myWriteBuffer = Encoding.ASCII.GetBytes(msg);
stream.Write(myWriteBuffer, 0, myWriteBuffer.Length);
byte[] myWriteBuffer2 = Encoding.ASCII.GetBytes("\r\n");
stream.Write(myWriteBuffer2, 0, myWriteBuffer2.Length);
string gResponse = "";
BinaryReader r = new BinaryReader(stream);
int receivedMessages = 0;
while (true)
{
while (true)
{
char currentChar = r.ReadChar();
if (currentChar == '\n')
break;
else
gResponse = gResponse + currentChar;
}
if (gResponse != "")
{
Console.WriteLine("RESPONSE:" + gResponse);
receivedMessages = receivedMessages + 1;
}
if (receivedMessages == 2)
{
break;
}
}
}
public static void Main()
{
List<string> messages = new List<string>();
for (int i = 0; i < 1; i++)
{
String msg = "{ \"user\" : \"James\", \"email\" : \"james#domain.pt\" }";
messages.Add(msg);
}
TcpClient client = new TcpClient();
client.Connect("someIp", somePort);
int sentMessages = 0;
int receivedMessages = 0;
foreach (string msg in messages)
{
Thread newThread = new Thread(() =>
{
sentMessages = sentMessages + 1;
Console.WriteLine("SENT MESSAGES: " + sentMessages);
SendMessage(client, msg);
receivedMessages = receivedMessages + 1;
Console.WriteLine("RECEIVED MESSAGES: " + receivedMessages);
});
newThread.Start();
}
Console.ReadLine();
}
}
If I send few emails (up to 10) the network stream is OK.
But if I send thousands of emails I get messed chars lie
:{iyo"asn ooyes" "ncd" 0,"s_d:"4379" nme" 92729,"er_u" ,"ed_t_i" 2#" p cin_d:"921891010-11:11.725,"s" 4663175D0105E6912ADAAFFF6FDA393367" rpy:"rcein"
Why is this?
Don't worry I'm not a spammer :D

When you write a message to a TCP socket, it'll respond with the sent data. When the buffer is full, I expect it's 0, but you advance your send buffer anyway. You should advance it by the return value :)
Edit: it looks like you're using a stream abstraction which writes the internal buffer. The situation is the same. You are saying "the message has been completely sent" when the internal buffer state is not saying this, i.e. position does not equal limit. You need to keep sending until the remaining amount of buffer is 0 before moving on.

I solved this issue by having a single method just to read from the stream like this:
private TcpClient client;
private NetworkStream stream;
public void ListenFromGateway()
{
...
while (true)
{
byte[] bytes = new byte[client.ReceiveBufferSize];
//BLOCKS UNTIL AT LEAST ONE BYTE IS READ
stream.Read(bytes, 0, (int)client.ReceiveBufferSize);
//RETURNS THE DATA RECEIVED
string returndata = Encoding.UTF8.GetString(bytes);
//REMOVE THE EXCEDING CHARACTERS STARTING ON \r
string returndata = returndata.Remove(returndata.IndexOf('\r'));
...
}
Thanks for the help

Related

Error IoTimedOut when reading data from the device

I used libUsbDotNet library (C#) to read data from USB device.
The program sees the device and turns to it, but gives a response IoTimedOut.
The program code is shown below.
public static UsbDeviceFinder MyUsbFinder = new UsbDeviceFinder(0x10C4, 0xEA61);
public static UsbDevice MyUsbDevice;
public static void Main()
{
MyUsbDevice = UsbDevice.OpenUsbDevice(MyUsbFinder);
if (MyUsbDevice == null) throw new Exception("Device Not Found.");
IUsbDevice wholeUsbDevice = MyUsbDevice as IUsbDevice;
if (!ReferenceEquals(wholeUsbDevice, null))
{
wholeUsbDevice.SetConfiguration(1);
wholeUsbDevice.ClaimInterface(0);
}
UsbEndpointReader reader = MyUsbDevice.OpenEndpointReader(ReadEndpointID.Ep01);
ErrorCode ec = ErrorCode.None;
int bytesRead = 0;
byte[] readBuffer = new byte[32];
while (true) {
Thread.Sleep(100);
ec = reader.Read(readBuffer, 1500, out bytesRead);
if (bytesRead > 0)
{
Console.WriteLine("Data Received");
// Console.Write(Encoding.Default.GetString(readBuffer, 0, bytesRead));
}
else {
Console.Write("Error type: ");
Console.WriteLine(ec);
Console.ReadKey();
MyUsbDevice.Close();
break;
}
}
}
I tried to change the reading parameters but it doesn't help. Can you please tell me what it may be related to, it is not clear to me from the libUsbDotNet documentation?

SNMP4j - Cannot send RESPONSE PDU on some OID

I'm trying to respond to SNMP GET requests from SnmpB with SNMP4j 2.3.1 (running on Windows).
In "Discover" mode, SnmpB queries by broadcasting 255.255.255.255 (checked with Wireshark) and I receive a GET request with standard OID (sysDescr, sysUpTime, sysContact, sysName and sysLocation). It finds my instance with the information I coded ("My System", "Myself", ...) (note that it also works when I enter the IP address under the "IP networks" textboxes, though I don't see any traffic on Wireshark but I receive the GET request):
I did write a very simple MIB file that I imported into SnmpB. It defines a single Integer32 data that I want to retrieve using an SNMP GET request from SnmpB.
However, using the same code than for the standard sys* OID, SnmpB doesn't seem to receive that data ("Timeout" in red on the top-right):
I did try Wireshark to check network activity and I don't see anything, so I guess it takes place on localhost (which is not accessible with Wireshark on Windows)? But the traces below show it does not (peerAddress=192.168.56.1)...
Here is the MIB file (code follows):
MY-TEST-MIB DEFINITIONS ::= BEGIN
IMPORTS
enterprises, MODULE-IDENTITY, OBJECT-TYPE, Integer32
FROM SNMPv2-SMI;
myTest MODULE-IDENTITY
LAST-UPDATED "201412301216Z"
ORGANIZATION "My org"
CONTACT-INFO "Matthieu Labas"
DESCRIPTION "MIB Test"
REVISION "201412301216Z"
DESCRIPTION "Generated"
::= { enterprises 12121 }
myData OBJECT-TYPE
SYNTAX Integer32
MAX-ACCESS read-only
STATUS current
DESCRIPTION "My data for test"
::= { myTest 1 }
END
... and the code:
public class RespondGET implements CommandResponder {
public static final OID sysDescr = new OID("1.3.6.1.2.1.1.1.0");
public static final OID sysUpTime = new OID("1.3.6.1.2.1.1.3.0");
public static final OID sysContact = new OID("1.3.6.1.2.1.1.4.0");
public static final OID sysName = new OID("1.3.6.1.2.1.1.5.0");
public static final OID sysLocation = new OID("1.3.6.1.2.1.1.6.0");
public static final OID myData = new OID("1.3.6.1.4.1.12121.1.0");
private Snmp snmp;
public RespondGET() throws IOException {
MessageDispatcher dispatcher = new MessageDispatcherImpl();
dispatcher.addMessageProcessingModel(new MPv2c()); // v2c only
snmp = new Snmp(dispatcher, new DefaultUdpTransportMapping(new UdpAddress("192.168.56.1/161"), true));
snmp.addCommandResponder(this);
snmp.listen();
}
#Override
public void processPdu(CommandResponderEvent event) {
System.out.println("Received PDU "+event);
PDU pdu = event.getPDU();
switch (pdu.getType()) {
case PDU.GET:
List<VariableBinding> responses = new ArrayList<VariableBinding>(pdu.size());
for (VariableBinding v : pdu.getVariableBindings()) {
OID oid = v.getOid();
// Answer the usual SNMP requests
if (sysDescr.equals(oid)) {
responses.add(new VariableBinding(oid, new OctetString("My System description")));
} else if (sysUpTime.equals(oid)) {
responses.add(new VariableBinding(oid, new TimeTicks(ManagementFactory.getRuntimeMXBean().getUptime())));
} else if (sysContact.equals(oid)) {
responses.add(new VariableBinding(oid, new OctetString("Myself")));
} else if (sysName.equals(oid)) {
responses.add(new VariableBinding(oid, new OctetString("My System")));
} else if (sysLocation.equals(oid)) {
responses.add(new VariableBinding(oid, new OctetString("In here")));
} else if (myData.equals(oid)) { // MyData handled here
responses.add(new VariableBinding(oid, new Integer32(18)));
}
}
try {
CommunityTarget comm = new CommunityTarget(event.getPeerAddress(), new OctetString(event.getSecurityName()));
comm.setSecurityLevel(event.getSecurityLevel());
comm.setSecurityModel(event.getSecurityModel());
PDU resp = new PDU(PDU.RESPONSE, responses);
System.out.println(String.format("Sending response PDU to %s/%s: %s", event.getPeerAddress(), new String(event.getSecurityName()), resp));
snmp.send(resp, comm);
} catch (IOException e) {
System.err.println(String.format("Unable to send response PDU! (%s)", e.getMessage()));
}
event.setProcessed(true);
break;
default:
System.err.println(String.format("Unhandled PDU type %s.", PDU.getTypeString(pdu.getType())));
break;
}
}
public static void main(String[] args) throws IOException {
RespondGET rg = new RespondGET();
System.out.println("Listening...");
int n = 300; // 5 min
while (true) {
try { Thread.sleep(1000); } catch (InterruptedException e) { }
if (--n <= 0) break;
}
System.out.println("Stopping...");
rg.snmp.close();
}
}
It produces the following output when I click "discover" under SnmpB and right-click on myData in the MIB Tree and "Get" (slightly reformatted for readability):
Listening...
Received PDU CommandResponderEvent[securityModel=2, securityLevel=1, maxSizeResponsePDU=65535,
pduHandle=PduHandle[16736], stateReference=StateReference[msgID=0,pduHandle=PduHandle[16736],
securityEngineID=null,securityModel=null,securityName=public,securityLevel=1,
contextEngineID=null,contextName=null,retryMsgIDs=null], pdu=GET[requestID=16736, errorStatus=Success(0), errorIndex=0,
VBS[1.3.6.1.2.1.1.1.0 = Null; 1.3.6.1.2.1.1.3.0 = Null; 1.3.6.1.2.1.1.4.0 = Null; 1.3.6.1.2.1.1.5.0 = Null; 1.3.6.1.2.1.1.6.0 = Null]],
messageProcessingModel=1, securityName=public, processed=false, peerAddress=192.168.56.1/49561, transportMapping=org.snmp4j.transport.DefaultUdpTransportMapping#120d62b, tmStateReference=null]
Sending response PDU to 192.168.56.1/49561/public: RESPONSE[requestID=0, errorStatus=Success(0), errorIndex=0,
VBS[1.3.6.1.2.1.1.1.0 = My System description; 1.3.6.1.2.1.1.3.0 = 0:01:03.18; 1.3.6.1.2.1.1.4.0 = Myself; 1.3.6.1.2.1.1.5.0 = My System; 1.3.6.1.2.1.1.6.0 = In here]]
Received PDU CommandResponderEvent[securityModel=2, securityLevel=1, maxSizeResponsePDU=65535,
pduHandle=PduHandle[1047], stateReference=StateReference[msgID=0,pduHandle=PduHandle[1047],
securityEngineID=null,securityModel=null,securityName=public,securityLevel=1,
contextEngineID=null,contextName=null,retryMsgIDs=null], pdu=GET[requestID=1047, errorStatus=Success(0), errorIndex=0,
VBS[1.3.6.1.4.1.12121.1.0 = Null]], messageProcessingModel=1, securityName=public, processed=false, peerAddress=192.168.56.1/49560, transportMapping=org.snmp4j.transport.DefaultUdpTransportMapping#120d62b, tmStateReference=null]
Sending response PDU to 192.168.56.1/49560/public: RESPONSE[requestID=0, errorStatus=Success(0), errorIndex=0, VBS[1.3.6.1.4.1.12121.1.0 = 18]]
Stopping...
What am I missing here? Could that "just" be a network routing issue?
After setting up a VM and checking with Wireshark, it turned out I forgot to set, on the response PDU, the same request ID than the GET PDU.
It was solved by adding resp.setRequestID(pdu.getRequestID()); when building the response PDU
CommunityTarget comm = new CommunityTarget(event.getPeerAddress(), new OctetString(event.getSecurityName()));
comm.setSecurityLevel(event.getSecurityLevel());
comm.setSecurityModel(event.getSecurityModel());
PDU resp = new PDU(PDU.RESPONSE, responses);
resp.setRequestID(pdu.getRequestID()); // Forgot that!
snmp.send(resp, comm);
Thanks to #Jolta for his patience during New Year holiday and his insisting on using Wireshark for further checking. :)

Read incoming sms without spaces

The following code reads an incoming sms then prints the body of the message. How do I get the app to print out the message without any spaces inbetween?
For example: The incoming sms reads "Here I am", so "Here I am" is printed out, but I want the app to print out "HereIam".
How can I do this? Any help would be most appreciated.
Here is my code:
public void run() {
try {
DatagramConnection _dc = (DatagramConnection)Connector.open("sms://");
for(;;) {
Datagram d = _dc.newDatagram(_dc.getMaximumLength());
_dc.receive(d);
byte[] bytes = d.getData();
String address = d.getAddress();
String msg = new String(bytes);
System.out.println(address);
System.out.println(msg);
}
}catch (Exception me) {
}
}
Thanks
try this
add this line to code
System.out.println(replaceAll(msg," ",""));
Add this method as well
public static String replaceAll(String source, String pattern,
String replacement) {
if (source == null)
return "";
StringBuffer sb = new StringBuffer();
int idx = -1;
int patIdx = 0;
while ((idx = source.indexOf(pattern, patIdx)) != -1) {
sb.append(source.substring(patIdx, idx));
sb.append(replacement);
patIdx = idx + pattern.length();
}
sb.append(source.substring(patIdx));
return sb.toString();
}
It replaces all the spaces with empty string, which is what you want.
Use the String.replace() method:
msg = msg.replace("\s+", "");

Getting a URL of a record from HP TRIM's Desktop Client

Is it possible to copy the URL of a Record/Document from HP's TRIM and sent it to someone in order to download?
Before TRIM 7, whether you can do this natively depends on which TRIM features are installed.
To see if you have the right stuff, make a TR5 file on your desktop, and rightclick on it - "TryURL" - copy the URL
(the TryURL right click action requires TRIM client stuff - if you don't have that, try opening the TR5 file in notepad, and see if there is a hyperlink in there).
You do get this functionality with the SharePoint connector for TRIM (TIPS or TSCI)
Or there is a cheap third party product that looks cool - from Icognition Pty Ltd.
There are a few ways of going about doing something like this. Assuming you're sending the link to someone on the same WAN, or the security-risky option of having your TRIM system internet accessible, what I'd do is build a simple web service over the top of the TRIM SDK. The TRIM SDK is COM (with a PIA wrapper) or a proper .Net assembly (in version 7.*), so a simple ASP.Net service would be quite easy.
Below is the code for an ASP.Net service I built, based on a code sample provided by HP (based on the TRIMSDKPIA20.dll, not the TRIM 7.0 HP.HPTRIM.SDK assembly). You could use it as a basis to make something more RESTful, but as it is, you'd call it using a URL like:
http://server/ViewRecord/recno=D11-001
You could then create an "External Link", an Addin based again on the SDK that you can register as a Right-Click option in the TRIM interface. Something like "Send Download URL..." that fires up an email and generates the URL, but that's a bit more complicated.
Anyway, the code for the webservice:
using System;
using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using TRIMSDK;
using System.Configuration;
using Microsoft.Win32;
using System.IO;
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
string errormsg = string.Empty;
//Response.Clear();
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Database trim = new Database();
trim.SetAsWebService();
trim.Id = ConfigurationSettings.AppSettings["dbid"];
trim.WorkgroupServerName = ConfigurationSettings.AppSettings["wgserver"];
trim.WorkgroupServerPort = Int32.Parse(ConfigurationSettings.AppSettings["wgport"]);
trim.Connect();
string recno = Request.QueryString["recno"];
if (String.IsNullOrEmpty(recno))
{
errormsg = "No recno parameter was passed.";
}
else
{
Record rec = trim.GetRecord(recno);
if (rec == null)
{
errormsg = string.Format("Could not find a record with number \"{0}\". Either it doesn't exist, or you don't have permission to view it.", recno);
}
else
{
if (!rec.IsElectronic)
{
errormsg = string.Format("Record {0} does not have an electronic attachment", rec.Number);
}
else
{
IStream s = rec.GetDocumentStream(null, false, null);
Response.ClearHeaders();
Response.AddHeader("Content-Disposition", "filename=" + rec.SuggestedFileName);
Response.AddHeader("Content-Length", rec.DocumentSize.ToString());
Response.Buffer = false;
Response.ContentType = GetContentType(rec.Extension);
uint BufferSize = 10000;
uint DocumentLength = (uint)rec.DocumentSize;
byte[] buffer = new byte[BufferSize];
uint bytesread;
uint totalread = 0;
Stream outstream = Response.OutputStream;
while (totalread < DocumentLength)
{
s.RemoteRead(out buffer[0], 10000, out bytesread);
if (bytesread < 10000)
{
for (uint i = 0; i < bytesread; i++)
{
outstream.WriteByte(buffer[i]);
}
}
else
{
outstream.Write(buffer, 0, 10000);
}
totalread += bytesread;
}
outstream.Close();
Response.Flush();
return;
}
}
}
Response.Write(errormsg);
}
private string GetContentType(string fileExtension)
{
string ct = Registry.GetValue(#"HKEY_CLASSES_ROOT\." + fileExtension.ToLower(), "Content Type", string.Empty) as string;
if (ct.Length == 0)
{
ct = "application/octet-stream";
}
return ct;
}
}

Grails Issue Dealing With Tcp Client & Tcp Server

I created a Tcp Client & Tcp Server in Groovy awhile back and had no issues with it. I was only connecting to one machine at the time to gather data. This time I am attempting to connect to the script on multiple hosts and it is only saving one of the hosts information in my grails app.
My Grails application is simple, it has a domain class for Machines (basically the computers and the information on them that I seek) and it will use my TcpClient.groovy script to connect and gather information from the TcpServer.groovy on the other computers. For each host, it should save the information gathered, however, it seems to skip right over saving any host aside from the last one.
Tcp Client :
//TCP CLIENT
public void queryData(def hosts) {
for(int aHost = 0; aHost < hosts.size; aHost++) {
cristalClient(hosts[aHost]);
}
}
public void cristalClient(String host) {
commands = ["dateScan", "computerName", "ip", "quit"]
answers = [commands.size]
requestSocket = new Socket(host, 2000)
r = new BufferedReader(new InputStreamReader(requestSocket.getInputStream()));
w = new BufferedWriter(new OutputStreamWriter(requestSocket.getOutputStream()));
String message = "Connection was successful"
message = readAvailable(r)
println("Sever>" + message)
for(int n = 0; n < commands.size; n++) {
sendMessage(commands[n]);
answers[n] = readAvailable(r)
}
lastRead = answers[0]
machineName = answers[1]
ipAddress = answers[3]
w.flush()
w.close()
}
public String readAvailable(r) {
String out = ""
String dum = null
while((dum = r.readLine()) !=null) {
if(dum == ">>EOF<<") return out
if(out.length() > 0) out += "\r\n"
out += dum
}
return out
}
public void sendMessage(msg) {
w.write(msg+"\r\n");
w.flush();
println("Client>" + msg);
}
public void printData(abc) {
abc.eachWithIndex { it, index ->
println "Drive $index"
it.each { k, v ->
println "\t$k = $v"
}
}
}
Tcp Server :
//TCP Server
def server = new ServerSocket(2000)
println("Waiting for connection")
server.accept() { socket ->
socket.withStreams { input, output ->
w = new BufferedWriter(new OutputStreamWriter(output))
String message = "Connection was successful"
r = new BufferedReader(new InputStreamReader(input))
while(true) {
if(message != null) {
sendMessage(message)
message = null
}
String a = r.readLine()
if(a == "dateScan") {
message = new Date
} else if(a == "computerName") {
message = InetAddress.getLocalHost().hostName
} else if(a == "ip") {
message = InetAddress.getLocalHost().getHostAddress()
} else if(a == "quit") {
server.close()
return
} else {
message = "$a command unknown."
println message
}
}
}
}
def sendMessage(String msg) {
println( "sending: >" + msg + "<" )
w.writeLine(msg)
w.writeLine(">>EOF<<")
w.flush();
}
Grails Controller :
//Grails Controller
CollectMachines {
def w = new tcpClient()
def hosts = ["winXp", "Win7"]
w.queryData(hosts)
def abc = w.hardDrive
abc.each { println it }
int numberOfDrives = abc.size()
//add new machine
numberOfDrives.times {
def machineName = abc.computerName[it]
def machineInstance = Machine.findByMachineName(machineName)
if (!machineInstance) {
machineInstance = new Machine(machineName)
}
def lastScan = abc.lastScan[it]
def scanDate = new Date().parse("E MMM dd H:m:s z yyyy", lastScan)
def ipAddress = abc.ipAddress[it]
machineInstance.setIpAddress(ipAddress)
machineInstance.setDateScanned(scanDate)
machineInstance.save()
}
redirect(action: "list")
}
Do I need to put a pause in so that the server has time to send a response? My Tcp Client does send out all the commands but only gets responses for the last set of commands.
Also, sorry for the indentation issues with my code snippets, I'm not sure why they are messed up.
.
There are a few problems with your code. tcpClient never assigns to hardDrive, for example. Assuming this is an oversight, I think the real problem is that tcpClient is querying data for multiple hosts, and storing all the results in the same instance variables answers, and ultimately lastRead, machineName, and ipAddress.
You need to store the results for each host separately. One way would be to have answers be a map of lists. For example, answers[host][0] would be the first answer for a given host.
I don't think any kind of pause is necessary.

Resources