SQL Service Broker完成其操作后发送TCP响应

时间:2015-01-20 20:40:41

标签: c# sockets tcp response tcplistener

我的应用程序当前侦听TCP端口并将入站数据解析为xml。我遇到的问题是应用程序需要发回包含由服务代理应用程序创建的不同xml集的响应。我对网络应用程序编程不熟悉,并且对入站/出站的处理方式没有充分的了解。在这一点上,一切都按预期工作,但我能看出的唯一响应是“来自客户端的最后消息 - ”+发送内容的回声。这是我的TCP服务器的代码...

public static void ReceivePortMessages()
{
    IPAddress ip = Dns.GetHostEntry("sctest.com").AddressList[0];
    TcpListener serverSocket = new TcpListener(ip, 8080);
    int requestCount = 0;
    TcpClient clientSocket = default(TcpClient);
    serverSocket.Start();
    Debug.Print(" >> Server Started");
    clientSocket = serverSocket.AcceptTcpClient();
    Debug.Print(" >> Accept connection from client");
    requestCount = 0;

    while (true)
    {
        try
        {
            requestCount = requestCount + 1;
            NetworkStream networkStream = clientSocket.GetStream();
            byte[] bytesFrom = new byte[10025];
            networkStream.Read(bytesFrom, 0, (int)clientSocket.ReceiveBufferSize);
            Stopwatch sw = new Stopwatch();
            sw.Start();
            string dataFromClient = System.Text.Encoding.ASCII.GetString(bytesFrom);
            dataFromClient = dataFromClient.Substring(0, dataFromClient.IndexOf("\0"));
            Debug.Print(" >> Data from client - " + dataFromClient);
            string serverResponse = "Last Message from client" + dataFromClient;
            Byte[] sendBytes = Encoding.ASCII.GetBytes(serverResponse);
            networkStream.Write(sendBytes, 0, sendBytes.Length);
            networkStream.Flush();
            Debug.Print(" >> " + serverResponse);

            try
            {
                XmlDocument xm = new XmlDocument();
                xm.LoadXml(string.Format("<root>{0}</root>", dataFromClient));
                XmlElement root = xm.DocumentElement;
                string rootName = root.FirstChild.Name;
                RouteInboundXML(rootName, dataFromClient, sw);
            }
            catch (Exception ex)
            {
                Debug.Print("Data provided does not match any predefined XML schemas; it will be ignored.");
            }
        }
        catch (ArgumentOutOfRangeException ex)
        {
            Debug.Print("Remote client disconnected.");
            clientSocket.Close();
            serverSocket.Stop();
            ReceivePortMessages();
            return;
        }
        catch (Exception ex)
        {
            Debug.Print(ex.ToString());
            clientSocket.Close();
            serverSocket.Stop();
            ReceivePortMessages();
            return;
        }
        Debug.Print(" >> exit");
    }
}

我真正需要发生的是发送响应的代码部分,在服务代理发布xml数据之后发送响应,修改它并将发回新的xml字符串。

private void PingReplyDependency()
{
    try
    {
        Stopwatch sw = new Stopwatch();
        sw.Start();
        if (!isPermitted())
        {
            return;
        }
        using (SqlConnection con = new SqlConnection(dbUSApp))
        using (SqlCommand cmd = con.CreateCommand())
        {
            cmd.CommandText = PING_AWAIT;
            cmd.CommandType = CommandType.Text;
            cmd.Notification = null;
            con.Open();
            using (SqlDataReader dr = cmd.ExecuteReader())
            {
                if (dr.HasRows)
                {
                    while (dr.Read())
                    {
                        PingReply ping = new PingReply();
                        ping.REPLY_CODE = dr["REPLY_CODE"].ToString();
                        WriteXMLFile<PingReply>(ping, string.Format(@"XML\PingSend{0}.xml", ping.TRAN_ID));

                        string rowPointer = dr["RowPointer"].ToString();
                        using (SqlConnection conInsert = new SqlConnection(dbP3USDApp))
                        using (SqlCommand cmdInsert = NonQueryCommand("[SP_DO_Xml]", conInsert,
                            new SqlParameter("@RowPointer", rowPointer)))
                        {
                            conInsert.Open();
                            cmdInsert.ExecuteNonQuery();
                        }
                    }
                }
            }
        }
    }
    catch (Exception ex)
    {
        ErrorLog.Write("Notification System", ex.ToString(), "SystemAvailabilityReply", Environment.UserName, "Failed Ping.");
    }
}

如果需要更多信息或清晰度,请告诉我。我试图只发布我认为必不可少的东西,但我可能从外部视角错过了一个重要的部分。提前谢谢。

1 个答案:

答案 0 :(得分:-1)

TCP是基于流的。这意味着TCP中没有应用程序消息的表示法。所有TCP都明白,它发送的是一个字节流,消息之间没有分离。

对于您而言,这意味着可以对邮件进行细分,以便您必须使用多个socket.Receive()来获取完整的邮件,或者在一个socket.Receive()中获得几条完整的邮件。

因此,您必须找出一些方法来了解消息的开始或结束位置。通常使用长度标头或消息分隔符。

如果您不想自己处理所有事情,可以使用我的Apache许可网络库:http://griffinframework.net/doc/networking