Trying to send a string containing a number of newline characters between words using TCPclient and C# where the newline characters needs to stay intact...
Working c++ example is here:
TCPClient->IOHandler->DefStringEncoding = enUTF8;
TCPClient->IOHandler->WriteLn("write text");
TCPClient->IOHandler->WriteLn("Test\n\n\nTest");
With this code the string shows up in the servers textfield the way I want: Test\n\n\nTest
But when trying c#:
clientStreamWriter.WriteLine("write text");
clientStreamWriter.WriteLine("Test\n\n\nTest");
This string shows up in the server textfield as: Test
Then the server returns a unknown command response... Seems as the StreamWriter breaks the string at the newline character and sends the rest as a new string and the server expects a new command.
How can I prevent this from happening? I have no idea what the server code is and writing in c++ is not an option for me :)
The problem is with your server protocol; you'll need to change the server to fix it. You need message framing.
Or you could just split your string up and send it as seperate calls ...
assuming your client is smart enough to figure out / your protocol defines an end messsage in some way?
TCPClient->IOHandler->DefStringEncoding = enUTF8;
TCPClient->IOHandler->WriteLn("write text");
TCPClient->IOHandler->WriteLn("[[begin]]");
TCPClient->IOHandler->WriteLn("Test");
TCPClient->IOHandler->WriteLn("");
TCPClient->IOHandler->WriteLn("");
TCPClient->IOHandler->WriteLn("");
TCPClient->IOHandler->WriteLn("Test");
TCPClient->IOHandler->WriteLn("[[end]]");
Related
I'm using WebApi 2.2 to ramp up on the Twilio API. I have the Twilio C# libraries installed.
I'm using a form to capture a string in my web app, and I send that down to webAPI. I'm wondering how I can leverage the C# libraries to send a message with line breaks.
The example code shows the following:
var msg = twilio.SendMessage("+15084043345", "+15084043345", "Can you believe it's this easy to send an SMS?!");
However, I'm not sure how to include a line break in this message. Should I be inserting anything into this string clientside to represent a linebreak? Any guidance would be awesome.
Twilio Evangelist here.
This is actually super simple:
var msg = twilio.SendMessage("+15084043345", "+15084043345", "Hello.\nCan you believe it's this easy to send an SMS?!");
Will result in:
Hello.
Can you believe it's this easy to send an SMS?!
Just like printing strings to the console, \n, \r\n, and \r can be used to insert a new line. I can't say definitively what is best to use across all handsets, but I have found \n to be pretty reliable. (I can say all three of these work on my iOS 8 device perfectly...)
If you want to show new line in sms like
Account Name : suraj
Age : 24
then here is a code for asp.net VB
Dim value As String = "Account Name :" & "suraj" & vbCrLf & "Age :" & " 24"
it will show new line in SMS not in web page
I am sending email body to the console application as parameter, the thing is I only see first 4 characters <div on the console application what happens to the other part? Can I send html email text as parameter to console application? Also is there any way to return a string[] array from console app?
My so far code below:
TestingConsoleApp to check the send n receive:
static void Main(string[] args)
{
string emailBody = System.IO.File.ReadAllText(#"C:\Users\ehsankayani\Desktop\email1Html.txt");
CallProcess(emailBody);
}
static void CallProcess(string body)
{
string path = #"F:\Scrappers\emailParser_app\emailParser_app\bin\Debug\emailParser_app.exe";
Process.Start(path, body);
}
Main console app:
static void Main(string[] args)
{
Console.WriteLine("EMAIL BODY = ");
string[] dataToReturn = new string[8];
//string emailBody = System.IO.File.ReadAllText(#"C:\Users\ehsankayani\Desktop\email1Html.txt");
string emailBody = args[0];
Console.WriteLine(emailBody);
Console.WriteLine(emailBody.Length);
Console.ReadLine();
var doc = new HtmlAgilityPack.HtmlDocument();
doc.LoadHtml(emailBody);
}
Any suggestions?
You are passing body as the parameter set in CallProcess. So if body were eg
xxxx yyyy ....
then args[0] would be just xxxx. You'll need to put "" around the text and escape in "'s in the text too.
A far better solution though would be to set up your Process to redirect stdin and to write the body to the process' stdin. This will avoid issues with whitespace and quotes. Take a look at http://msdn.microsoft.com/en-us/library/system.diagnostics.processstartinfo.redirectstandardinput.aspx for details on doing this.
A simply HttpUtility.EncodeHtml(Emailbody) while sending and HttpUtility.DecodeHtml(emailBody) on receiving does the job.
Since you ask for suggestions: For complex and/or large data, I'd rather pass only the information where to find the data to the process being called. Same can be done for returned data
This has several positive effects, the more complex and the larger these data are: You don't have to make sure the data are matching the command line restrictions, you don't have to allocate lots of memory to encode/decode the data in both processes, and you don't need to implement the logic to do that. Instead, write the data into a file, a shared memory region (MMF) or the like and pass that address.
Nearly the only downside is that you have to think about who's responsible for cleaning up.
Another possible approach could involve interprocess communication, but I think that's a bit overkill here.
I'm using Jon Skeet's (excellent) port of Google's Protocol Buffers to C#/.Net.
For practice, I have written a dummy Instant Messenger app that sends some messages down a socket. I have a message definition as follows:-
message InstantMessage {<br/>
required string Message = 1;<br/>
required int64 TimeStampTicks = 2; <br/>
}
When the sender serialises the message, it sends it really elegantly:-
...
InstantMessage.Builder imBuild = new InstantMessage.Builder();
imBuild.Message = txtEnterText.Text;
imBuild.TimeStampTicks = DateTime.Now.Ticks;
InstantMessage im = imBuild.BuildPartial();
im.WriteTo(networkStream);
...
This works great. But at the other end, I'm having trouble getting the ParseFrom to work.
I want to use:-
InstantMessage im = InstantMessage.ParseFrom(networkStream);
But instead I have had to read it to bytes and then parse it from here. This is obviously not ideal for a number of reasons. Current code is:-
while (true)
{
Byte[] byteArray = new Byte[10000000];
int intMsgLength;
int runningMsgLength = 0;
DateTime start = DateTime.Now;
while (true)
{
runningMsgLength += networkStream.Read(byteArray, runningMsgLength, 10000000 - runningMsgLength);
if (!networkStream.DataAvailable)
break;
}
InstantMessage im = InstantMessage.ParseFrom(byteArray.Take(runningMsgLength).ToArray());
When I try to use ParseFrom, control does not return to the calling method even when I know a valid GB message is on the wire.
Any advice would be gratefully received,
PW
Sorry for taking a while to answer this. As Marc says, protocol buffers don't have a terminator, and they aren't length prefixed unless they're nested. However, you can put on the length prefix yourself. If you look at MessageStreamIterator and MessageStreamWriter, you'll see how I do this - basically I pretend that I'm in the middle of a message, writing a nested message as field 1. Unfortunately when reading the message, I have to use internal details (BuildImpl).
There's now another API to do this: IMessage.WriteDelimitedTo and IBuilder.MergeDelimitedFrom. This is probably what you want at the moment, but I seem to remember there's a slight issue with it in terms of detecting the end of the stream (i.e. when there isn't another message to read). I can't remember whether there's a fix for it at the moment - I have a feeling it's changed in the Java version and I may not have ported the change yet. Anyway, that's definitely the area to look at.
Protobuf has no terminator - so either close the stream, or use your own length prefix etc. Protobuf-net exposes this easily via SerializeWithLenghtPrefix / DeserializeWithLengthPrefix.
Simply: without this, it can't know where each message ends, so keeps trying to read to the end of the stream.
I have to do a Windows application that from times to times access a Gmail account and checks if there is a new email. In case there is, it must read the email body and subject (a simple text email, without images or attachments).
Please, do not use paid libs, and in case of any other libs used, give the download path.
And I need the email body and subject only. So if the long and complex message that comes from Gmail could be parsed and only two strings containing the subject and the body, it would be perfect.
Finally, I only have to get the new messages arrived since the last execution. So the read messages could be marked as "read" and only the new ones (marked as "new") are considered.
The code can be written in Python or C++, but I prefer it in C#.
Related question:
Properly formatted example for Python iMAP email access?
This prints the subject and body of unseen messages, and marks those messages as seen.
import imaplib
import email
def extract_body(payload):
if isinstance(payload,str):
return payload
else:
return '\n'.join([extract_body(part.get_payload()) for part in payload])
conn = imaplib.IMAP4_SSL("imap.gmail.com", 993)
conn.login("user", "password")
conn.select()
typ, data = conn.search(None, 'UNSEEN')
try:
for num in data[0].split():
typ, msg_data = conn.fetch(num, '(RFC822)')
for response_part in msg_data:
if isinstance(response_part, tuple):
msg = email.message_from_string(response_part[1])
subject=msg['subject']
print(subject)
payload=msg.get_payload()
body=extract_body(payload)
print(body)
typ, response = conn.store(num, '+FLAGS', r'(\Seen)')
finally:
try:
conn.close()
except:
pass
conn.logout()
Much of the code above comes from Doug Hellmann's tutorial on imaplib.
Use one of the many C# IMAP libraries.
Note that there are some differences between Gmail-IMAP and IMAPA. For example, due to the fact that Gmail treats folders like labels, the code like the one below doesn't delete message if it's tagged with some other folder:
imap_instance.uid('store', uid, '+FLAGS', '\\Deleted')
imap_instance.expunge()
I know this is an old post but I wanted to add the following link to the Open Source ImapX 2 Library discussion: https://imapx.codeplex.com/ the developers seem to be keeping the project up to date. Great job to those all involved
Google has opened it's Gmail API for accessing your gmail account. You can check a quickstart sample with the basic functionalities at this link:
https://developers.google.com/gmail/api/quickstart/python
from imap_tools import MailBox, Q
# This prints the subject and body of unseen messages, and marks those messages as seen.
with MailBox('imap.mail.com').login('test#mail.com', 'password') as mailbox:
# *mark_seen param = True by default
print([(m.subject, m.html or m.text) for m in mailbox.fetch(Q(seen=False), mark_seen=True)])
imap_tools
I'm trying to get a C++ service to load an XML document from a MSMQ message generated by C#. I can't really change the C++ side of things because I'm trying to inject test messages into the queue. The C++ service is using the following to load the XML.
CComPtr<IXMLDOMDocument2> spDOM;
CComPtr<IXMLDOMNode> spNode;
CComBSTR bstrVal;
if(_FAILED(hr = spDOM.CoCreateInstance(CLSID_DOMDocument30)))
{
g_infoLog->LogCOMError(hr, "CWorker::ProcessBody() Can't Create DOM");
pWork->m_nFailure = WORKFAIL_BADXML;
goto Exit;
}
hr = spDOM->loadXML(bstrBody, &vbResult);
The C# code to send the MSMQ message looks like this (just test code not pretty):
// open the queue
var mq = new MessageQueue(destinationQueue)
{
// store message on disk at all intermediaries
DefaultPropertiesToSend = { Recoverable = true },
// set the formatter to Binary, default is XML
Formatter = new BinaryMessageFormatter()
};
// send message
mq.Send(messageContent, "TestMessage");
mq.Close();
I tried to send the same message using BinaryMessageFormatter but it puts what I think are unicode characters at the top before the XML starts.
.....ÿÿÿ
ÿ.......
......À)
If I use the default XML formatter the message has the following top element. The C++ service doesn't seem to handle this.
<?xml version="1 .0"?>..<string>& lt;
Do you know of a way I could easily clean up the unicode characters when using the binary formatter? If so I think it might work.
Have you tried the ActiveXMessageFormatter? It might not compile with it as the formatter, i have no way to test here, but it might.
EDIT: just tried and it compiles ok, whether the result is any better i still couldn't say for sure.