- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
通过 TCP 对 Linux 'C' write() 的 3 次调用发送的 3 个数据 block ,通过 Windows C# .BeginReceive() 接收相同的 3 个数据 block ,或者一个连续的数据 block ,或者不管有多少已经被接收在调用 .BeginReceived 时收到?
Linux 上的“C”应用程序通过 3 次 write() 调用通过 TCP 连接将消息发送到 Windows C# 应用程序,该应用程序使用 BeginReceive() 进行接收。
是否需要调用 BeginReceive() 三次,以接收 write() 发送的三个 block 中的每一个?还是 BeginReceive() 接收到的大小等于调用 BeginReceive() 时 Windows 接收到的大小?这可能是 3 个 writes() 发送的所有字节,也可能是部分字节,因此应该调用 .BeginReceive() 直到收到所有字节?
Linux C 应用程序在嵌入式 TI ARM 上运行,Windows C# 应用程序在同一个盒子内运行单板计算机。 ARM 具有与 SBC 的直接以太网连接。
ARM 和 SBC 之间的通信有时无法在启动时启动,我正在对源代码进行逆向工程以检查是否存在不良设计。
ARM端为TCP监听器,Windows客户端发起TCP连接。
使用 MontaVista(R) Linux(R) 专业版 5.0.0 (0702774)和 Windows-7 Visual-Studio 2010 Visual-C#。
这里是ARM发送软件,Windows接收软件......................................................................
LINX 'C'
char msgBuffer[64];
sprintf(msgBuffer, START_MSG_ENVELOPE, msgId++, ack);
write(connection->fd, msgBuffer, strlen(msgBuffer));
write(connection->fd, msg, strlen(msg));
write(connection->fd, END_MSG_ENVELOPE, strlen(END_MSG_ENVELOPE));
这是它的 WINDOWS C# 端...................................... ……
private static void makeConnection(Socket clientSocket, int iPortNo)
{
TimeoutObject.Reset();
socketexception = null;
IPAddress ip;
//create the end point
IPEndPoint ipEndPoint;
ip = IPAddress.Parse(ipAddress);
try
{
ipEndPoint = new IPEndPoint(ip, iPortNo);
//connect to the remote host...
clientSocket.BeginConnect(ip, iPortNo, new AsyncCallback(CallBackMethod), clientSocket);
if (TimeoutObject.WaitOne(5 * 1000, false)) //5 secs connection timeout
{
if (!IsConnectionSuccessful)
{
string msg = VNResourceManager.Instance.GetString(VNMessages.DAM_NOT_FOUND);
if (socketexception != null)
msg += ": " + socketexception.Message;
throw new Exception(msg);
}
}
else
{
clientSocket.Close();
throw new TimeoutException(VNResourceManager.Instance.GetString(VNMessages.CONNECTION_TO_DAM_TIMED_OUT));
}
//watch for data ( asynchronously )...
WaitForData();
}
catch (SocketException e)
{
socketexception = e;
throw;
}
}
private static void CallBackMethod(IAsyncResult asyncresult)
{
try
{
IsConnectionSuccessful = false;
Socket socket = asyncresult.AsyncState as Socket;
if (socket.Connected)
{
socket.EndConnect(asyncresult);
IsConnectionSuccessful = true;
}
}
catch (Exception ex)
{
IsConnectionSuccessful = false;
socketexception = ex;
}
finally
{
TimeoutObject.Set();
}
}
public static void WaitForData()
{
try
{
if (asyncCallBack == null)
{
asyncCallBack = new AsyncCallback(OnDataReceived);
}
CSocketPacket theSocPkt = new CSocketPacket();
theSocPkt.thisSocket = clientSocket;
asyncResult = clientSocket.BeginReceive(theSocPkt.dataBuffer, 0, theSocPkt.dataBuffer.Length, SocketFlags.None, asyncCallBack, theSocPkt);
}
catch (SocketException se)
{
notifyErrorEventSubscribers(se);
}
}
public static void send(string message)
{
try
{
byte[] byData = System.Text.Encoding.ASCII.GetBytes(message);
clientSocket.Send(byData);
}
catch (SocketException se)
{
notifyErrorEventSubscribers(se);
throw;
}
}
//[MethodImpl(MethodImplOptions.Synchronized)]
public static void OnDataReceived(IAsyncResult result)
{
try
{
CSocketPacket theSockId = (CSocketPacket)result.AsyncState;
//end receive...
int messageSize = 0;
messageSize = theSockId.thisSocket.EndReceive(result);
Console.WriteLine(">>>>>>>>> messageSize = " + messageSize); // !!!
char[] chars = new char[messageSize + 1];
System.Text.Decoder d = System.Text.Encoding.ASCII.GetDecoder();
int charLen = d.GetChars(theSockId.dataBuffer, 0, messageSize, chars, 0);
string replyMessage = new System.String(chars);
lock (syncLock) //LastIndexOf function accesses the current culture info and we clear it in WM_TIMECHANGE handler (protecting from that race condition here)
{
if (replyMessage.LastIndexOf("\0") > 0)
replyMessage = replyMessage.Remove(replyMessage.LastIndexOf("\0"), 1);
if (replyMessage.LastIndexOf(Terminator) > 0)
replyMessage = replyMessage.Remove(replyMessage.LastIndexOf(Terminator), 1);
}
// Continue the waiting for data on the Socket
WaitForData();
receivedMsg += replyMessage;
// only serialize when we feel we have a message or we have reached the message line limit
if (((receivedMsg.Contains("message") && receivedMsg.Contains("/>")) || receivedMsg.Contains("</message>")) /* || (mRecvdMsgLineCount == Message.kMaxLines) */ )
{
List<XmlMessage> msgList = new List<XmlMessage>();
int index = -1;
do
{
index = receivedMsg.IndexOf("</message>");
if (index != -1)
{
XmlMessage message;
string strMessage = receivedMsg.Substring(0, index + "</message>".Length);
//MessageBox.Show(strMessage);
strMessage = strMessage.TrimStart(new char[] { '\r', '\n' });
receivedMsg = receivedMsg.Remove(0, index + "</message>".Length);
try
{
message = (XmlMessage)XmlMessage.GetXmlSerializer().Deserialize(XmlReader.Create(new StringReader(strMessage)));
}
catch (InvalidOperationException error)
{
string strErrorMessage = error.Message;
if (error.InnerException != null)
strErrorMessage += "\r\n" + error.InnerException.Message;
notifyErrorEventSubscribers(new Exception(strErrorMessage + "\r\n-----------------------------------------------------------------\r\n" + strMessage));
return;
}
msgList.Add(message);
}
} while (index != -1);
StringWriter sw = new StringWriter();
string serializedXml = string.Empty;
string strXmlMessage = string.Empty;
foreach (XmlMessage message in msgList)
{
if (message.ack_required && (message.update == null))
{
XmlMessage messageAcknowledge = new XmlMessage();
messageAcknowledge.ack_required = false;
messageAcknowledge.ack = new ack();
messageAcknowledge.ack.success = true;
messageAcknowledge.ack.id = message.id;
try
{
sendMessage(messageAcknowledge);
}
catch(Exception ex)
{
Logger.Log(EnumLoggingLevel.Error, "SocketCommunicationXMl.OnDataReceived", ex.Message);
}
}
if (dataReceivedEvent != null)
{
dataReceivedEvent(new object(), new DataReceivedEventArgs(message));
}
if ((ackRequiredMsg != null) && (message.ack != null))
{
if ((message.ack.id == ackRequiredMsg.id) && message.ack.success)
{
eventWaitForAck.Set();
}
}
}
}
}
catch (ObjectDisposedException objectDisposedException)
{
// Dispatcher.dispatchDebug(Debug.Level_3,"Socket has been closed", this);
notifyErrorEventSubscribers(objectDisposedException);
}
catch (SocketException se)
{
if (se.ErrorCode == 10054)
{
/*
for (int i = 0; i < 50; i++)
{
Thread.Sleep(1000);
}
try
{
SocketCommunicationDaq.Reconnect();
}
catch(Exception ex)
{
VNMsgBox.Show(ex.Message, MsgButtonType.OkOnly, MsgIconType.Error);
return;
}
clientSocket.Shutdown(SocketShutdown.Both);
clientSocket.Close();
for (int i = 0; i < 3; i++)
{
try
{
connect();
break;
}
catch (Exception ex)
{
System.Threading.Thread.Sleep(5000);
}
}
*/
Logger.Log(EnumLoggingLevel.Error, "OnDataReceived: ", se.ToString());
}
else
{
notifyErrorEventSubscribers(se);
}
}
}
最佳答案
正如其他人所提到的,TCP 是一种流式传输协议(protocol),因此您永远无法知道要获取全部 100 个字节需要多少次 DataReceived 回调。可以是 1,也可以是 100。
接收代码相当复杂,性能有待提高(字符串操作太多)。很难判断是否存在控制流问题。我建议分解 DataReceived 方法以进行简化。这是一个合理的框架:
public static void OnDataReceived(IAsyncResult result)
{
//1) copy all data received into a buffer of some sort, like MemoryStream
//2) Dispatch any/all full messages that have been received
// to a queue or handler method (maybe handle on another thread)
//(hold onto any leftover bytes received that are part of the next message)
//Call BeginReceive() again
}
此外,如果您使用长度前缀消息格式,它还可以帮助简化框架。
关于c# - 应该调用 C# .BeginReceive() 多少次以接收发送的 3 个 block ,即通过 TCP 对 Linux C write() 的 3 次调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21800665/
我正在执行 UPDATE .WRITE() 语句,并发现它显然只有在您像这样定义它时才有效: string sql = "UPDATE [dbo].[Table] SET [Column].WRITE
我在 Unix 系统上用 C 编程。我知道: write(fd,"ABCD",4); 比这样做更好: write(fd, "A", 1); write(fd, "B", 1); write(fd, "
func hash(s string) uint32 { h := fnv.New32a() h.Write([]byte(s)) return h.Sum32() } 对于这
在经典的 asp 页面中,有人告诉我您可以使用 vbscript 或 jscript。而 jscript 就是 javascript。 所以我不确定 Response.Write、Response.W
当 openssl 子进程尝试 write() 到本地目录时,我收到此错误。在调用 write() 之前连接已关闭。它没有与 ssl 连接,因为我什至无法从 nodejs 文档启动示例代码。 我错过了
最近我在试验netty。我遇到了以下问题: ctx.channel().write(new TextWebSocketFrame("hello")) 没有在客户端返回 hello,但是 ctx.cha
请解释以下内容: def feed(data): import os print "DATA LEN: %s" % len(data) f = open("copy", "w") f.
有什么区别debug.write 和 Trace.write ?每个应该什么时候使用? 最佳答案 在典型的发布构建配置中,Debug class 被禁用并且什么都不做。 Trace但是,仍然可以在发行
我只是想知道,就性能而言,哪个更好(我在 FileStream 中使用 StreamWriter): 多次调用 Stream.Write(): StreamWriter sw = new Stream
我发现自己写给 stringwriter,然后在函数末尾执行 resp.Write(sw.ToString())。这是不必要的吗?如果我多次使用 HttpResponse.Write,即使我的页面是
我正在尝试通过 JavaScript 文件从 electron 打开一个新窗口,它可以工作,并打开了新窗口,但我无法将 HTML/文本写入新文件。我收到那个错误: Cannot read proper
我们对 QIODevice::write 的一般行为和具体的 QTcpSocket 实现感到非常困惑。有一个 similar question已经,但答案并不令人满意。主要的混淆源于分别提到的 byt
我知道这听起来像是一个愚蠢的问题: write(*,*) 和 write(6,*) ?我在我研究所的 super 计算机上运行一个复杂的代码,它通过一个不同于 6 的单元号输出一个数据文件,显然编译的
我有一个结构体,它可以通过一系列复杂的方法调用转换为文本,其中包含大量 write!调用。此文本可以写入文件或调试日志。我正在决定是否使用 fmt::Write 或 io::Write .我不能真正使
已关闭。这个问题是 not reproducible or was caused by typos 。目前不接受答案。 这个问题是由拼写错误或无法再重现的问题引起的。虽然类似的问题可能是 on-top
In the C standard library, an output can't be followed by an input and vice versa. 对于Linux API,可以在re
我希望能够为一件事做 document.write。然后延迟半秒,然后再记录。写一些。你知道这是否可能吗?而且,如果是这样,怎么办?到目前为止,我已经尝试过了,但没有奏效: document.writ
为什么通过 onclick 属性调用的 write() 函数解析为 document.write() 并替换文档?有什么办法可以阻止这种情况发生吗? Write Function Alternat
我想创建一个包含多个“页面”的文本文件,并将每个页面的字节偏移量记录在一个单独的文件中。为此,我将字符串打印到主输出文件并使用 bytes_written += file.write(str) 计算字
关闭。这个问题需要更多focused .它目前不接受答案。 想改进这个问题吗? 更新问题,使其只关注一个问题 editing this post . 关闭 8 年前。 Improve this qu
我是一名优秀的程序员,十分优秀!