相关文章推荐
寂寞的烤红薯  ·  PHP正则应用09 —— ...·  1 年前    · 
拉风的猴子  ·  react-antd选择器选择多属性传值_a ...·  2 年前    · 
可爱的伏特加  ·  桌面窗口管理器 dwm.exe ...·  2 年前    · 
酒量小的太阳  ·  Verilog语法速成(二) - 知乎·  3 年前    · 
小百科  ›  应该调用多少次C# .BeginReceive()才能接收三个块--通过TCP对Linux C写()的3个调用?开发者社区
string tcp socket
坚强的机器猫
2 年前
首页
学习
活动
专区
工具
TVP 最新优惠活动
返回腾讯云官网
提问

问 应该调用多少次C# .BeginReceive()才能接收三个块--通过TCP对Linux C写()的3个调用?

Stack Overflow用户
提问于 2014-02-15 16:54:16
EN

通过TCP对Linux 'C‘write()的3个调用发送的3个块是否被Windows C# .BeginReceive()接收为相同的三个块,还是单个连续块,或者在调用.BeginReceived时收到了多少块?

Linux上的一个'C‘应用程序通过3个调用发送消息,通过TCP连接将()写到一个使用C# ()接收的Windows BeginReceive应用程序。

是否需要调用BeginReceive()三次,以接收write()发送的三个块中的每个块?或者BeginReceive()接收的大小是否等于调用BeginReceive()时所接收的大小?哪个字节可以是3写()发送的所有字节,也可以是部分数量,所以应该调用.BeginReceive(),直到全部接收到为止?

Linux应用程序是在嵌入式TI ARM上运行的,在同一个盒子里,Windows C#应用程序运行的是一台单板计算机。ARM与SBC有一个直接的以太网连接。

ARM和SBC之间的通信有时无法在启动时启动,我正在反向工程源代码以检查错误的设计。

ARM端是TCP侦听器,Windows客户端启动TCP连接。

使用MontaVista(R) Linux(注册商标)专业版5.0.0 (0702774)和Windows7Visual-Studio 2010 Visual#。

这是ARM发送软件和Windows接收软件.

LINX 'C‘

代码语言: javascript
复制
        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));

这里是IT.............................................的WINDOWS C#端

代码语言: javascript
复制
        private static void makeConnection(Socket clientSocket, int iPortNo)
        TimeoutObject.Reset();
        socketexception = null;
        IPAddress ip;
        //create the end point 
        IPEndPoint ipEndPoint;
        ip = IPAddress.Parse(ipAddress);
            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);
                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)
            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()
            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)
            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)
            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;
                    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);
                            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;
                            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);
                    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++)
                        connect();
                        break;
                    catch (Exception ex)
                        System.Threading.Thread.Sleep(5000);
                Logger.Log(EnumLoggingLevel.Error, "OnDataReceived: ", se.ToString());
                notifyErrorEventSubscribers(se);
    }
2 675 0 票数 0
EN
c#
c
linux
sockets
tcp

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-02-18 16:52:22

正如其他人所提到的,TCP是一种流协议,因此您永远无法知道获得全部100个字节需要多少DataReceived回调。可能是1,可能是100。

接收代码相当复杂,性能可以提高(太多的字符串操作)。很难说是否存在控制流问题。我建议打破DataReceived方法来简化。这里有一个合理的骨架:

代码语言: javascript
复制
    public static void OnDataReceived(IAsyncResult result)
        //1) copy all data received into a buffer of some sort, like MemoryStream
 
推荐文章
寂寞的烤红薯  ·  PHP正则应用09 —— 把多余的空格替换成一个空格-CSDN博客
1 年前
拉风的猴子  ·  react-antd选择器选择多属性传值_antd select 多选 赋值-CSDN博客
2 年前
可爱的伏特加  ·  桌面窗口管理器 dwm.exe 突然占用高GPU - Microsoft Community
2 年前
酒量小的太阳  ·  Verilog语法速成(二) - 知乎
3 年前
今天看啥   ·   Py中国   ·   codingpro   ·   小百科   ·   link之家   ·   卧龙AI搜索
删除内容请联系邮箱 2879853325@qq.com
小百科 - 百科知识指南
© 2024 ~ 沪ICP备11025650号