使用ASP.Net命名管道

时间:2011-12-04 15:25:05

标签: c# asp.net .net

我在控制台应用程序和asp.net-app之间有一个命名管道。当我尝试从asp.net页面发送一些东西到控制台时,它完全可以工作..但不是其他。

Codebehind(asp):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Runtime.InteropServices;
using Microsoft.Win32.SafeHandles;
using System.IO;
using System.Text;
using System.Threading;

namespace TESTASP
{
    public partial class _Default : System.Web.UI.Page
    {
        NamedPipeClient nc;
        NamedPipeServer ns;
        protected void Page_Load(object sender, EventArgs e)
        {
            nc = new NamedPipeClient("myNamedPipe1");
            ns = new NamedPipeServer("myNamedPipe2");
            nc.ClientListen();
            if (!IsPostBack)
            {
                ns.newstring += new NewString(np_newstring);
                Thread t = new Thread(new ThreadStart(ns.ServerListen));
                t.Start();
            }
        }

        void np_newstring(string text)
        {
           this.Session["string"] = text;
        }

        protected void Button1_Click(object sender, EventArgs e)
        {
            nc.Write("test");
        }

        protected void Timer1_Tick1(object sender, EventArgs e)
        {
            Label1.Text = (string)Session["string"];
        }
    }
}

问题在于:

this.Session["string"] = text;

当我调试项目时,“text”中有一个值,但它说:

(用谷歌翻译翻译......)

  

只有在a中设置enableSessionState时才能使用会话状态   配置文件或在页面指令中为“true”。还要确保   System.Web.SessionStateModule或自定义会话状态模块   应用程序配置在\ \    部分包括在内。

NamedPipeServer类看起来像:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Microsoft.Win32.SafeHandles;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;

namespace TESTASP
{
    public class NamedPipeServer
    {
        static FileStream fStream;
        private const uint DUPLEX = (0x00000003);
        private const uint FILE_FLAG_OVERLAPPED = (0x40000000);

        private string PIPE_NAME = "\\\\.\\pipe\\myNamedPipe";
        private const uint BUFFER_SIZE = 4096;

        public event NewString newstring;

        public NamedPipeServer(string name)
        {
            PIPE_NAME = "\\\\.\\pipe\\" + name;
        }

        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern SafeFileHandle CreateNamedPipe(
           String pipeName,
           uint dwOpenMode,
           uint dwPipeMode,
           uint nMaxInstances,
           uint nOutBufferSize,
           uint nInBufferSize,
           uint nDefaultTimeOut,
           IntPtr lpSecurityAttributes);

        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern int ConnectNamedPipe(
           SafeFileHandle hNamedPipe,
           IntPtr lpOverlapped);

        public void ServerListen()
        {

            SafeFileHandle clientPipeHandle;
            while (true)
            {
                clientPipeHandle = CreateNamedPipe(
                   PIPE_NAME,
                   DUPLEX | FILE_FLAG_OVERLAPPED,
                   0,
                   255,
                   BUFFER_SIZE,
                   BUFFER_SIZE,
                   0,
                   IntPtr.Zero);

                //failed to create named pipe
                if (clientPipeHandle.IsInvalid)
                    break;

                int success = ConnectNamedPipe(
                   clientPipeHandle,
                   IntPtr.Zero);

                //failed to connect client pipe
                if (success != 1)
                    break;
                else
                {
                    fStream = new FileStream(clientPipeHandle, FileAccess.ReadWrite, 4096, true);
                    string test = Read();
                    if (!test.Equals("###"))
                        newstring(test);
                }
            }

        }

        private string Read()
        {
            byte[] buffer = new byte[BUFFER_SIZE];
            ASCIIEncoding encoder = new ASCIIEncoding();

            while (true)
            {
                int bytesRead = fStream.Read(buffer, 0, 4096);

                //could not read from file stream
                if (bytesRead == 0)
                    return "###";


                return encoder.GetString(buffer).TrimEnd('\0');
            }
        }

        public void Write(string message)
        {
            ASCIIEncoding encoder = new ASCIIEncoding();
            byte[] sendBuffer = encoder.GetBytes(message);
            fStream.Write(sendBuffer, 0, sendBuffer.Length);
            fStream.Flush();
        }
    }
}

Web.Config:

<configuration>

  <connectionStrings>
    <add name="ApplicationServices"
         connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|\aspnetdb.mdf;User Instance=true"
         providerName="System.Data.SqlClient" />
  </connectionStrings>

  <system.web>

    <httpModules>
      <add name="Session" type="System.Web.SessionState.SessionStateModule"/>
    </httpModules>

    <pages enableSessionState="true"/>

    <compilation debug="true" targetFramework="4.0">
      <assemblies>
        <add assembly="System.Data.Entity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
      </assemblies>
    </compilation>

    <authentication mode="Forms">
      <forms loginUrl="~/Account/Login.aspx" timeout="2880" />
    </authentication>

    <membership>
      <providers>
        <clear/>
        <add name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider" connectionStringName="ApplicationServices"
             enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false"
             maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10"
             applicationName="/" />
      </providers>
    </membership>

    <profile>
      <providers>
        <clear/>
        <add name="AspNetSqlProfileProvider" type="System.Web.Profile.SqlProfileProvider" connectionStringName="ApplicationServices" applicationName="/"/>
      </providers>
    </profile>

    <roleManager enabled="false">
      <providers>
        <clear/>
        <add name="AspNetSqlRoleProvider" type="System.Web.Security.SqlRoleProvider" connectionStringName="ApplicationServices" applicationName="/" />
        <add name="AspNetWindowsTokenRoleProvider" type="System.Web.Security.WindowsTokenRoleProvider" applicationName="/" />
      </providers>
    </roleManager>



  </system.web>

  <system.webServer>
     <modules runAllManagedModulesForAllRequests="true"/>
  </system.webServer>


</configuration>

我希望你能帮助我:S

提前致谢!

1 个答案:

答案 0 :(得分:1)

我不确定你想要达到什么目标。您在页面请求中启动一个线程以从管道接收数据。当您调用此页面时,线程将被启动但请求可能在答案来自管道之前终止,您无法再写入会话数据。

您只能访问当前webcontext中的Session。

HttpContext.Current.Session

如果从外部线程调用,则为null。