hope someone can help me with this issue. I have been trying different things for a while and I have tried a few solutions that I found on here and other site to no avail but as I am a novice, I think I have probably missed something. Here goes.
I am writing an application and I want to add in the ability for users to send messages to each other and have them pop on the screen. This is fine, the message is delivered and the form pops but if the user sends another message, it creates a new instance of the class. It doesn't appear to be finding the open form. I have tried a few things to search through open forms:
//Receive message is started by the OpenListeningSocket function
//ProcessingThread = new Thread(() => ReceiveMessage());
private void ReceiveMessage()
{
Socket newSocket = tempServerSocket;
NetworkStream netStream = new NetworkStream(newSocket);
BinaryReader br = new BinaryReader(netStream);
BinaryWriter bw = new BinaryWriter(netStream);
String message;
String sender;
try
{
do
{
message = br.ReadString();
sender = br.ReadString();
} while (br.PeekChar() > 0);
/*
//FormCollection fc = Application.OpenForms;
for(int i = 0; i <= Application.OpenForms.Count; i++)
//foreach (Form frm in Application.OpenForms)
{
if(Application.OpenForms[i].Text == sender)
//if (frm is Message)
{
Message liveMessage = (Message)Application.OpenForms[i];
if (liveMessage.Text == sender)
{
MessageBox.Show("liveMessage Message detected");
liveMessage.lbMain.Items.Add(sender + ": " + message);
liveMessage.cbUsers.Text = sender;
liveMessage.cbUsers.Enabled = false;
liveMessage.TopMost = true;
liveMessage.TopMost = false;
liveMessage.ShowDialog();
//liveMessage.Visible = true;
}
}
else if(Application.OpenForms[i] is Message)
{
newMsg = new Message();
newMsg.Text = sender;
newMsg.userName = userName;
newMsg.cbUsers.Text = sender;
newMsg.cbUsers.Enabled = false;
newMsg.lbMain.Items.Add(sender + ": " + message);
//msgList.Add(newMsg);
newMsg.ShowDialog();
}
}
*/
if (msgList.Count < 1)
{
Message newMsg = new Message();
newMsg.Text = sender;
newMsg.userName = userName;
newMsg.cbUsers.Text = sender;
newMsg.cbUsers.Enabled = false;
newMsg.lbMain.Items.Add(sender + ": " + message);
msgList.Add(newMsg);
newMsg.Visible = true;
}
else
{
foreach (Message msg in msgList)
{
if (msg.Text == sender)
{
//Message msg = (Message)frm;
msg.lbMain.Items.Add(sender + ": " + message);
msg.cbUsers.Text = sender;
msg.cbUsers.Enabled = false;
newMsg.Visible = true;
//msg.Visible = true;
}
}
}
}
catch(Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
I have tried looking through all the open forms in the Form Collection and if the form is of the Message class, cast it to Message. I couldn't get this to work. I tried adding all new Message instances to a Generic List of type Message and then iterating through them but this didn't work, maybe being disposed by the ProcessingThread?
I have tried looking at some instant messaging application examples but I haven't come across how they send the new message to the existing form.
If anyone has any helpful hints or could point me in the right direction, it would be greatly appreciated. Thanks, Cameron.
Related
The code worked fine, I got a task to append some more data to the mail body, but when i started testing before adding any new work. But this error has occured on the test version of the project even though a colleague was testing the code a few weeks ago and hasn't made any changes to the code since then. I tried:
changing the sender -- no luck,
tried with various reciever e-mails (all different domains) - no change
Exception
public void r105Implementation(InboxModel instance)
{
var assignedToUser = VUsers.SelectSingle("UserID=#guid", new FieldValue("#guid", instance.AssignedToUserID));
if (instance.AssignedToUserID != instance.CurrentUserID)
{
var smtpSection = (SmtpSection)ConfigurationManager.GetSection("system.net/mailSettings/smtp");
StringBuilder sb = new StringBuilder();
sb.Append("Poštovani,");
sb.AppendLine();
sb.AppendLine("Dodijeljen Vam je zadatak putem sustava održavanja");
sb.AppendLine();
sb.AppendLine("Detalje provjerite na aplikaciji: http://somepage.com/");
sb.AppendLine();
sb.AppendLine("Administrator DZZ");
var mailMessage = new MimeMailMessage();
mailMessage.BodyEncoding = System.Text.Encoding.GetEncoding("iso-8859-2");
mailMessage.SubjectEncoding = System.Text.Encoding.GetEncoding("iso-8859-2");
mailMessage.IsBodyHtml = true;
mailMessage.Subject = "Novi zadatak";
using (System.Net.Mail.AlternateView sbPart = System.Net.Mail.AlternateView.CreateAlternateViewFromString(sb.ToString(), System.Text.Encoding.UTF8, "text/plain"))
{
mailMessage.IsBodyHtml = false;
sbPart.TransferEncoding = System.Net.Mime.TransferEncoding.QuotedPrintable;
mailMessage.AlternateViews.Add(sbPart);
mailMessage.Body = sb.ToString();
}
mailMessage.From = new MimeMailAddress(smtpSection.From);
mailMessage.To.Add(assignedToUser.Email);
var emailer = new MimeMailer();
emailer.Host = smtpSection.Network.Host;
emailer.Port = smtpSection.Network.Port;
if (smtpSection.Network.EnableSsl)
emailer.SslType = SslMode.Ssl;
else
emailer.SslType = SslMode.None;
emailer.User = smtpSection.Network.UserName;
emailer.Password = smtpSection.Network.Password;
emailer.AuthenticationMode = AuthenticationType.Base64;
emailer.MailMessage = mailMessage;
emailer.SendCompleted += Emailer_SendCompleted;
//emailer.OnMailSent += new SendCompletedEventHandler(OnMailSent);
try
{
emailer.SendMailAsync(mailMessage);
}
catch (Exception e) {
}
Result.Continue();
Result.ShowViewMessage("Email poslan dodijeljenoj osobi!");
}
}
private void Emailer_SendCompleted(object sender, AsyncCompletedEventArgs e)
{
//if (e.UserState != null)
Console.Out.WriteLine(e.UserState.ToString());
if (e.Error != null)
{
// test1
}
else if (!e.Cancelled)
{
// test2
}
}
}
So my code was working just fine. But now, even though I can confirm the variables and strings are there through a Clipboard copy, the textblocks are not updating via TextBlock.Text. Did I turn something off? Every single one stopped doing it at the same time.
`private void actionPing_Click(object sender, RoutedEventArgs e)
{
try
{
Ping myPing = new Ping();
PingReply reply = myPing.Send(HostNameIPTyped.Text.ToString(), 500);
if (reply != null)
{
string tripTime = reply.RoundtripTime.ToString();
if (tripTime == "0")
{
PingStatus1.Foreground = new System.Windows.Media.SolidColorBrush((Color)ColorConverter.ConvertFromString("#660000"));
PingStatus1.Text = "Device not found"; <---NONE OF THESE ARE UPDATING ACROSS THE ENTIRE PROGRAM
}
else
{
PingStatus1.Foreground = new System.Windows.Media.SolidColorBrush((Color)ColorConverter.ConvertFromString("#17b05c"));
PingStatus1.Text = "Ping Successful, " + reply.RoundtripTime.ToString() + "ms roundtrip";
//// LET'S GET THE IP AND HOSTNAME OF WHATEVER THE HELL YOU PUT IN
////IPADDRESS
try
{
System.Net.IPAddress ip = System.Net.Dns.GetHostEntry(HostNameIPTyped.Text.ToString()).AddressList.Where(o => o.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork).First();
ipAddress = ip.ToString();
}
catch (Exception ex)
{ }
////HOSTNAME
try
{
System.Net.IPHostEntry hostEntry = System.Net.Dns.GetHostEntry(ipAddress);
machineName = hostEntry.HostName;
string linkBuild = "http://" + machineName;
}
catch (Exception ex) { }
PingStatus1.Text += " " + machineName;
}
}
}
catch
{
{
PingStatus1.Foreground = new System.Windows.Media.SolidColorBrush((Color)ColorConverter.ConvertFromString("#660000"));
PingStatus1.Text = "Device not found";
}
}
}`
It was updating the fields. I had made an adjustment to the size of the grid which flattened all of the textblock fields to the left side. Once I drug them out they were no longer auto-sized.
Thanks for the help!
On my server side I have set up a single thread code that creates a new Socket object every time a client connects. Then I pass whatever I get from the client along with the socket that is connected to a packet handler and do the calculations there. In my main form I have a listview that I populate via entity framework, and whenever a packet from a registered computer connects I update the listview. So my question is can I from the packet handler class pass the socket object to the tag property of my listview when I update it?
My server side code:
private void ReceivedCallback(IAsyncResult result)
{
Socket clientSocket = result.AsyncState as Socket;
SocketError ER;
try
{
int bufferSize = clientSocket.EndReceive(result, out ER);
if (ER == SocketError.Success)
{
byte[] packet = new byte[bufferSize];
Array.Copy(_buffer, packet, packet.Length);
Console.WriteLine("Handling packet from IP:" + clientSocket.RemoteEndPoint.ToString());
//Handle packet stuff here.
PacketHandler.Handle(packet, clientSocket);
_buffer = new byte[61144];
clientSocket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, ReceivedCallback, clientSocket);
//clientSocket.BeginReceive(new byte[] { 0 }, 0, 0, 0, ReceivedCallback, clientSocket);
}
else
{
Console.WriteLine("No bytes received, we're closing the connection.");
clientSocket.Close();
}
}catch(SocketException ex)
{
Console.WriteLine("We caught a socket exception:" + ex.Message);
clientSocket.Close();
}
}
And my packet handler class:
public static void Handle(byte[] packet, Socket clientSocket)
{
if (clientSocket.Connected)
{
if (packet.Length > 0)
{
IPEndPoint RemoteIP = (IPEndPoint)clientSocket.RemoteEndPoint;
ushort packetLength = BitConverter.ToUInt16(packet, 0);
ushort packetType = BitConverter.ToUInt16(packet, 2);
ushort packetID = BitConverter.ToUInt16(packet, 4);
Console.WriteLine("We received a packet of Type: {0}, ID: {1} FROM {2}", packetType, packetID, RemoteIP.ToString());
if (packetType == 1)
{
switch (packetID)
{
case 1://Check if computer is registered in the database
CheckRegisteredRequest request1 = new CheckRegisteredRequest(packet);
Console.WriteLine("We received (Case 1): " + request1.Text);
string Response = "";
bool found = false;
ServerDbContext database = new ServerDbContext();
foreach (computers pcs in database.computers)
{
if (pcs.name == request1.Text.Split(',')[0])
{
found = true;
if (pcs.computer_ip == request1.Text.Split(',')[1])
{
//We found a computer with that name and ip address
Response = "true";
CheckRegisteredResponse resp1 = new CheckRegisteredResponse(Response);
clientSocket.Send(resp1.Data);
computers registeredPC;
var name = request1.Text.Split(',')[0];
using (var ctx = new ServerDbContext())
{
registeredPC = ctx.computers.Where(c => c.name == name).FirstOrDefault<computers>();
}
if (registeredPC != null)
{
registeredPC.networkStatus = "online";
}
using (var ctx = new ServerDbContext())
{
ctx.Entry(registeredPC).State = System.Data.Entity.EntityState.Modified;
ctx.SaveChanges();
}
addNewLog("Computer: " + request1.Text.Split(',')[0] + " came online - IP: " + request1.Text.Split(',')[1]);
RaiseFeedback("PC: " + request1.Text.Split(',')[0] + " came online - IP: " + request1.Text.Split(',')[1]);
break;
}
else
{
//We found a computer with that name but a different ip address, update it
var name = request1.Text.Split(',')[0];
var registeredPC = new computers();
using (var ctx = new ServerDbContext())
{
registeredPC = ctx.computers.Where(c => c.name == name).FirstOrDefault<computers>();
}
if (registeredPC != null)
{
var ip = request1.Text.Split(',')[1];
registeredPC.computer_ip = ip;
registeredPC.networkStatus = "online";
}
using (var ctx = new ServerDbContext())
{
ctx.Entry(registeredPC).State = System.Data.Entity.EntityState.Modified;
ctx.SaveChanges();
}
Response = "true";
CheckRegisteredResponse resp1 = new CheckRegisteredResponse(Response);
clientSocket.Send(resp1.Data);
addNewLog("Computer: " + request1.Text.Split(',')[0] + " came online - IP: " + request1.Text.Split(',')[1]);
RaiseFeedback("PC: " + request1.Text.Split(',')[0] + " came online - IP: " + request1.Text.Split(',')[1]);
break;
}
}
}
if (!found)
{
//There is no computer with that name in the database so send false
Response = "false";
CheckRegisteredResponse resp1 = new CheckRegisteredResponse(Response);
clientSocket.Send(resp1.Data);
}
break;... and so on....
So I've tried via a handler:
this is my custom event handler Args:
public class TextArgs : EventArgs
{
#region Fields
private string szMessage;
private Socket _sockets123;
#endregion Fields
#region ConstructorsH
public TextArgs(string TextMessage,Socket sock)
{
if (sock != null)
{
_sockets123 = sock;
szMessage = TextMessage;
}
else
{
szMessage = TextMessage;
}
}
#endregion Constructors
#region Properties
public string Message
{
get { return szMessage; }
set { szMessage = value; }
}
public Socket _socket
{
get { return _sockets123; }
set { _sockets123 = value; }
}
#endregion Properties
}
This is how i define that handler at the PacketHandler class:
public static event LogsEventHandler Feedback;
private static void RaiseFeedback(string p, Socket sock)
{
LogsEventHandler handler = Feedback;
if (handler != null)
{
handler(null,new TextArgs(p,sock));
}
}
And whenever a computer registers or connects I do the following:
RaiseFeedback("PC: " + request1.Text.Split(',')[0] + " came online - IP: " + request1.Text.Split(',')[1], clientSocket);
or
RaiseFeedback("PC: " + request1.Text.Split(',')[0] + " came online - IP: " + request1.Text.Split(',')[1], null);
And the event fires of these two methods in my main form:
private void OnFeedbackReceived(object sender, TextArgs e)
{
Invoke((MethodInvoker)delegate
{
UpdateComputers();
UpdateGUI(e.Message,e._socket);
}
);
}
public void UpdateGUI(string s, Socket sock)
{
LogBox.Text += s;
LogBox.AppendText(Environment.NewLine);
using (var context = new ServerDbContext())
{
var PCInfo = context.viewUsersInfo;
dataGridView1.DataSource = PCInfo.ToList();
}
if (sock != null)
{
ListViewItem item = ComputersList.FindItemWithText(s.Split(':')[1].ToString());
item.Tag = sock;
}
}
The Question: Yes, you can. Control.Tag is of type object and can hold pretty much anything you choose.
So you can write
Socket socket = someSocket;
ListViewItem item = listView1.FindItemWithText(someText);
if (item != null) item.Tag = socket; else Console.WriteLine(someText + " not found!);
And retrieve it as:
if (item.Tag != null) someSocket = item.Tag AS socket;
if (someSocket != null) ..
It is up to you to watch out for the success of the cast when retrieving it but also if the Socket still is alive and well..
The problem: The stackoverflow in your code is due to an erreanous, short-circuited property, which you have fixed by now. In general, you only need to write explicit getter and setters if they actually do more than just gettin and setting.
They could log out out test data, update other, dependent properties, do checks or conversiones or do other stuff.
But if none of it is needed, simply don't create the private fields and write the automatic getter and setters:
public Socket MySocket {get; set;}
Also note that the naming convention asks you to capitalize proprety names!
I have been tasked with writing a custom application in C#.NET to move messages from one queue to another, while keeping all of the context and identity information the same as the original message.
I have tried to decipher the online docs, and have tried every combination of MQC.MQOO_PASS_ALL_CONTEXT and MQOO_SAVE_ALL_CONTEXT in opening queues, and MQC.MQPMO_PASS_ALL_CONTEXT in put calls, to no avail. I have tried setting the MQPutMessageOptions.ContextReference to both the source and the
destination queues, but I continue to get exceptions, either MQRC_CONTEXT_HANDLE_ERROR or MQRC_OPTIONS_ERROR, and I cannot find enough information in the online docs to determine the problem.
I am using runtime version v2.0.50727, Version 7.5.0.1 of the amqmdnet.dll. If anyone knows the correct open and/or put message option settings I need to use, I would appreciate the leg up. Thanks.
***** SECOND UPDATE *****
Here is a very simple gui program to test the classes, and I get the same results:
public partial class frmMain : Form
{
// Simple test - all data hard-coded
string sourceQStr = "PETE.TQ1";
string targetQStr = "PETE.TQ2";
string targetMsgIdStr = "414D5120514D4942584330352020202028ED0155202EB302";
string connName = "localhost";
string connPort = "1414";
MQQueueManager sourceManager;
MQQueueManager targetManager;
MQQueue sourceQueue;
MQQueue targetQueue;
MQMessage msg = new MQMessage();
MQGetMessageOptions gmo = new MQGetMessageOptions();
MQPutMessageOptions pmo = new MQPutMessageOptions();
public frmMain()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void txtPassword_Validating(object sender, CancelEventArgs e)
{
if (txtPassword.Text.Trim() != string.Empty)
{
if (LoginUser())
btnTest.Focus();
else
txtUserId.Focus();
}
}
public void LogoutUser()
{
txtUserId.Text = "";
txtPassword.Text = "";
btnTest.Enabled = false;
}
public bool LoginUser()
{
bool OK = ValidateUserAndPassword();
if (OK)
{
btnTest.Enabled = true;
}
else LogoutUser();
return OK;
}
private bool ValidateUserAndPassword()
{
if ((txtUserId.Text.Trim() == string.Empty) || (txtPassword.Text.Trim() == string.Empty))
return false;
try
{
bool _passwordValid = false;
ContextOptions options = ContextOptions.SimpleBind | ContextOptions.SecureSocketLayer;
using (PrincipalContext pc = new PrincipalContext(ContextType.Domain, "UP"))
{
_passwordValid = pc.ValidateCredentials
(txtUserId.Text.Trim(), txtPassword.Text.Trim(), options);
}
if (!_passwordValid)
MessageBox.Show("Invalid username / password", "Invalid",
MessageBoxButtons.OK, MessageBoxIcon.Error);
return _passwordValid;
}
catch (PrincipalServerDownException pex)
{
string msg = pex.Message.Insert(pex.Message.IndexOf("server"), "Authentication ");
MessageBox.Show(msg, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
}
private void btnTest_Click(object sender, EventArgs e)
{
try
{
SetupObjects();
sourceQueue.Get(msg, gmo);
targetQueue.Put(msg, pmo);
sourceManager.Commit();
targetManager.Commit();
MessageBox.Show("Test appears successful - verify with MQ Explorer","OK",
MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
catch (Exception ex) // MQRC_CONTEXT_HANDLE_ERROR is always thrown
{
MessageBox.Show("Error: " + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
sourceManager.Backout();
targetManager.Backout();
}
}
private void btnClose_Click(object sender, EventArgs e)
{
this.Close();
}
/************************************** Utiility methods *****************************************/
private void SetupObjects()
{
// set up objects
string connectName = connName + "(" + connPort + ")";
int ConnOptions = MQC.MQCNO_HANDLE_SHARE_BLOCK;
sourceManager = new MQQueueManager("", ConnOptions, "CHANNEL1", connectName);
targetManager = new MQQueueManager("", ConnOptions, "CHANNEL1", connectName);
MQEnvironment.UserId = txtUserId.Text.Trim();
MQEnvironment.Password = txtPassword.Text.Trim();
int options =
MQC.MQOO_INPUT_SHARED + MQC.MQOO_FAIL_IF_QUIESCING +
MQC.MQOO_SAVE_ALL_CONTEXT + MQC.MQOO_INQUIRE;
sourceQueue = sourceManager.AccessQueue
(sourceQStr, options, sourceManager.Name, null, txtUserId.Text.Trim());
options =
MQC.MQOO_OUTPUT + MQC.MQOO_FAIL_IF_QUIESCING +
MQC.MQOO_PASS_ALL_CONTEXT + MQC.MQOO_INQUIRE;
targetQueue = targetManager.AccessQueue
(targetQStr, options, targetManager.Name, null, txtUserId.Text.Trim());
int i = 0;
try
{
i = sourceQueue.CurrentDepth;
}
catch (Exception ex)
{
MessageBox.Show("Exception: " + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
gmo.Options = MQC.MQGMO_COMPLETE_MSG + MQC.MQGMO_FAIL_IF_QUIESCING +
MQC.MQGMO_NO_WAIT + MQC.MQGMO_SYNCPOINT;
pmo.Options = MQC.MQPMO_PASS_ALL_CONTEXT +
MQC.MQPMO_SYNCPOINT + MQC.MQPMO_SYNC_RESPONSE;
pmo.ContextReference = sourceQueue;
msg.MessageId = StringToByteArray(targetMsgIdStr);
}
public byte[] StringToByteArray(String hex)
{
hex = hex.Trim();
int NumberChars = hex.Length;
if ((NumberChars % 2) != 0)
{
hex = "0" + hex;
NumberChars++;
}
byte[] bytes = new byte[NumberChars / 2];
for (int i = 0; i < NumberChars; i += 2)
bytes[i / 2] = StringToByte(hex.Substring(i, 2));
return bytes;
}
public byte StringToByte(string hexDigits)
{
if (hexDigits.Length != 2)
return 0;
int high = hexValue(hexDigits[0]);
int low = hexValue(hexDigits[1]);
return (byte)(((high << 4) & 240) | (low & 15));
}
public int hexValue(char c)
{
int retval = 0;
if (c > '9')
retval = ((int)c) - 55;
else
retval = ((int)c) - 48;
return retval;
}
}
The GUI simply prompts for a username and password (which are validated with an LDAP call) and then enables a "test" button which runs the btnTest_Click method. I still get the same exception (MQRC_CONTEXT_HANDLE_ERROR) even thought I have used all the open and get message options specified.
Adding to Morag's answer, here is snippet for moving messages with context. I am also using a SYNC_POINT to ensure the message is removed from source queue after the message is successfully put to the destination queue.
/// <summary>
/// Moves messages from one queue to another with context
/// </summary>
public void moveMessagesWithContext()
{
MQQueueManager qmSource = null;
MQQueueManager qmDestination = null;
MQQueue qSource = null;
MQQueue qDestination = null;
Hashtable htSource = null;
Hashtable htDestination = null;
try
{
htSource = new Hashtable();
htDestination = new Hashtable();
htSource.Add(MQC.TRANSPORT_PROPERTY, MQC.TRANSPORT_MQSERIES_MANAGED);
htSource.Add(MQC.HOST_NAME_PROPERTY, "localhost");
htSource.Add(MQC.PORT_PROPERTY, 2020);
htSource.Add(MQC.CHANNEL_PROPERTY, "A_QM_SVRCONN");
qmSource = new MQQueueManager("A_QM", htSource);
qSource = qmSource.AccessQueue("Q_SOURCE", MQC.MQOO_INPUT_AS_Q_DEF | MQC.MQOO_FAIL_IF_QUIESCING | MQC.MQOO_SAVE_ALL_CONTEXT);
htDestination.Add(MQC.TRANSPORT_PROPERTY, MQC.TRANSPORT_MQSERIES_MANAGED);
htDestination.Add(MQC.HOST_NAME_PROPERTY, "localhost");
htDestination.Add(MQC.PORT_PROPERTY, 3030);
htDestination.Add(MQC.CHANNEL_PROPERTY, "B_QM_SVRCONN");
qmDestination = new MQQueueManager("B_QM", htDestination);
qDestination = qmDestination.AccessQueue("Q_DESTINATION", MQC.MQOO_OUTPUT | MQC.MQOO_FAIL_IF_QUIESCING | MQC.MQOO_PASS_ALL_CONTEXT);
MQMessage msgSource = new MQMessage();
MQGetMessageOptions gmo = new MQGetMessageOptions();
gmo.Options |= MQC.MQGMO_SYNCPOINT;
qSource.Get(msgSource,gmo);
if (msgSource != null)
{
MQMessage msgDestination = new MQMessage();
MQPutMessageOptions pmo = new MQPutMessageOptions();
pmo.ContextReference = qSource;
qDestination.Put(msgSource, pmo);
qmSource.Commit();
}
}
catch (MQException mqEx)
{
qmSource.Backout();
Console.WriteLine(mqEx);
}
catch (Exception otherEx)
{
Console.WriteLine(otherEx);
}
}
The correct options to use to move messages whilst retaining all the context information within them are as follows.
When opening the queue to get messages from, use MQOO_SAVE_ALL_CONTEXT. The context will be saved at get time in the object handle that represents this opened queue.
When opening the queue to put messages to, use MQOO_PASS_ALL_CONTEXT. Then when putting the message, use MQPMO_PASS_ALL_CONTEXT and provide the object handle that contains the context.
Receiving return code MQRC_CONTEXT_HANDLE_ERROR means that you didn't use MQOO_SAVE_ALL_CONTEXT on the first open but then tried to use the object handle on the put. It could also mean that it's just not a correct reference to the first queue. In the MQ API it's an object handle (MQHOBJ) whereas in .Net it's the MQQueue (see MQPutMessageOptions .NET class).
Receiving return code MQRC_OPTIONS_ERROR means that you mixed and matched the options too much.
The problem - I can't get this functions working. I see in LogCat that socket is connected to c# server, but I don't see received data. What I'm doing wrong?
Here is c# function with MessageBoxes for checking:
private void receiveConnection(){
Socket myHandler = null;
bool isConnected = false;
while (true)
{
if (!isConnected)
{
myHandler = wSocket.Accept();
isConnected = true;
MessageBox.Show("We have client!");
}
if (sendDataToAndroid)
{
try
{
sendDataToAndroid = false;
NetworkStream stream = new NetworkStream(myHandler);
StreamWriter sw = new StreamWriter(stream);
string myMsg = "";
myMsg += temp_F.Length + " ";
temp_F[0] = 3.151F;
temp_F[1] = 1.415F;
temp_F[2] = 5.572F;
temp_F[3] = 6.320F;
for (int i = 0; i < temp_F.Length; i++)
{
myMsg += temp_F[i] + " ";
}
byte[] msg = Encoding.ASCII.GetBytes(myMsg);
MessageBox.Show("Data to send: " + myMsg);
try
{
myHandler.Send(msg);
MessageBox.Show("Data has been sent!");
}
catch (Exception e) {
MessageBox.Show("Error while sending data!");
}
}
catch (Exception e)
{
isConnected = false;
myHandler.Close();
myHandler = null;
MessageBox.Show("Error while sending data...");
}
}
}
}
And here is Android function which is always trying to receive data:
public class SendThread implements Runnable {
public void run()
{
Socket socket = null;
BufferedReader in = null;
while (true)
{
// Loop until connected to server
while (socket == null){
try{
socket = new Socket ("192.168.137.1", 808);
}
catch (Exception e) {
socket = null;
}
}
// Get from the server
try {
Log.d("Connection: ", "connected");
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String line = null;
while ((line = in.readLine()) != null) {
Log.d("Socket:", line);
NumberFormat nf = new DecimalFormat ("990,0");
String[] tokens = line.split(" ");
int currTempSize = Integer.parseInt(tokens[0]);
currentTemp = new double[currTempSize];
for (int i = 0; i < currTempSize; i++)
currentTemp[i] = (Double) nf.parse(tokens[i+1]);
//Toast.makeText(getApplicationContext(), "Received data:", duration)
for (int i = 0; i < currTempSize; i++){
Log.d("Converted data: currentTemp["+i+"] = ", currentTemp[i]+"");
}
}
}
catch (Exception e) {
socket = null;
in = null;
Log.d("Connection: ", "lost.");
}
}
}
}
Your Java code reads a line at a time but you never sent a line terminator from C#.
You could append one to myMsg manually, or you could use the sw.WriteLine() method on your StreamWriter (which don't otherwise seem to be using). After calling sw.WriteLine() you will probably have to call sw.Flush().