这些线程是否共享数据?

时间:2015-03-18 00:16:39

标签: c# multithreading tcpclient tcpserver

你好我现在对我得到的错误感到困惑。错误是

System.dll中出现未处理的“System.IO.IOException”类型异常

其他信息:无法将数据写入传输连接:远程主机强行关闭现有连接。

是由这行代码引起的

this.StreamWriter.WriteLine("Number of items can not be 0 or less");

然而,此错误仅发生在大约50%的时间。因为我的项目涉及多线程,所以我认为我的线程在某种程度上共享一个streamWriter并在其他线程可以使用它之前关闭它。相反,每个线程创建自己,就像我试图做的那样。以下是一些相关代码:

private static void Main(string[] args)
    {
         TcpListener server = null;
        Thread thread1 = null;
        Thread thread2 = null;
        Thread thread3 = null;
    try
    {
        // Set the TcpListener on port 12000.
        Int32 port = 12000;
        IPAddress localAddr = IPAddress.Parse("127.0.0.1");

        // TcpListener server = new TcpListener(port);
        server = new TcpListener(localAddr, port);

        // Start listening for client requests.
        server.Start();


        // Enter the listening loop.
        Console.Write("Waiting for a connection... ");
        bool full = false;
        while (true)
        {
           //the code seen blow is to insure that only 3 threads are running at once.
            if (!full)
            {          

                if (thread1 == null)
                {
                    TcpClient client = server.AcceptTcpClient();
                    HandleClient handleObj = new HandleClient(client, myInventory);
                    thread1 = new Thread(handleObj.HandleNewClient);
                    thread1.Start();
                }
                else if (!thread1.IsAlive)
                {
                    TcpClient client = server.AcceptTcpClient();
                    HandleClient handleObj = new HandleClient(client, myInventory);
                    thread1 = new Thread(handleObj.HandleNewClient);
                    thread1.Start();
                }
                if (thread2 == null)
                {
                    TcpClient client = server.AcceptTcpClient();
                    HandleClient handleObj = new HandleClient(client, myInventory);
                    thread2 = new Thread(handleObj.HandleNewClient);
                    thread2.Start();
                }
                else if (!thread2.IsAlive)
                {
                    TcpClient client = server.AcceptTcpClient();
                    HandleClient handleObj = new HandleClient(client, myInventory);
                    thread2 = new Thread(handleObj.HandleNewClient);
                    thread2.Start();
                }
                if (thread3 == null)
                {
                    TcpClient client = server.AcceptTcpClient();
                    HandleClient handleObj = new HandleClient(client, myInventory);
                    thread3 = new Thread(handleObj.HandleNewClient);
                    thread3.Start();
                }
                else if (!thread3.IsAlive)
                {
                    TcpClient client = server.AcceptTcpClient();
                    HandleClient handleObj = new HandleClient(client,myInventory);
                    thread3 = new Thread(handleObj.HandleNewClient);
                    thread3.Start();
                }
            }


            if (thread1.IsAlive && thread2.IsAlive && thread3.IsAlive)
            {
                full = true;
                Console.Write("Server is full");
               // Console.ReadLine();
            }
            else
            {
                full = false;
                 Console.Write("Server is not full");
                //Console.ReadLine();
            }

        }

HandleClient类:

class HandleClient
{
    private StreamWriter StreamWriter { set; get; }
    private StreamReader StreamReader { set; get; }
    private TcpClient Client { set; get; }
    private NetworkStream NetworkStream { set; get; }
    private Inventory myInventory;
    public object Locker = new object();

    public HandleClient(TcpClient client, Inventory myInventory)
    {
        this.Client = client;
        this.myInventory = myInventory;
        this.NetworkStream = client.GetStream();
        this.StreamWriter = new StreamWriter(NetworkStream);
        this.StreamReader = new StreamReader(NetworkStream);
    }

    public void HandleNewClient()
    {
        Console.WriteLine("A new Client Connected!");
        String theString;
        try
        {


            string[] input = GetValidInput();
            lock (Locker)
            {
                input[0] = input[0].ToLower();
                input[1] = input[1].ToLower();
                if (input[0].Equals("r"))
                {
                    this.StreamWriter.WriteLine(this.myInventory.ReturnItem(input[1], Convert.ToInt32(input[2])));
                    //Console.WriteLine("wrote to clint");
                }
                else if (input[0].Equals("b"))
                {

                    this.StreamWriter.WriteLine(this.myInventory.BuyItem(input[1], Convert.ToInt32(input[2])));
                    // Console.WriteLine("wrote to clint");
                }
                this.StreamWriter.Flush();
            }


        }

        finally
        {
            //Console.WriteLine(Thread.CurrentThread.ManagedThreadId + "is about to close stuff");
            this.StreamReader.Close();
            this.StreamWriter.Close();
            this.NetworkStream.Close();
            this.Client.Close();

        }
    }

    private string[] GetValidInput()
    {
        bool valid = false;
        int numVal = -1;
        string[] values = new string[3];
        string theString = null;
        while (!valid)
        {
            while (String.IsNullOrEmpty(theString))
            {
                theString = StreamReader.ReadLine();
                Console.WriteLine("this is theString = " + theString);
            }

            values = theString.Split(',');
            if (values.Count() != 3)
            {
                this.StreamWriter.WriteLine("Invalid number of arguments please try again");
            }
            try
            {
                numVal = Convert.ToInt32(values[2]);
            }
            catch (FormatException e)
            {
                this.StreamWriter.WriteLine("thrid value is not a sequence of digits.");

            }
            if (numVal < 1)
            {
                this.StreamWriter.WriteLine("Number of items can not be 0 or less");
            }
            else
            {
                valid = true;
                Console.WriteLine("got Valid input");
            }
        }
        return values;
    }

克林特方面:

class Client
{
    static void Main(string[] args)
    {
        for (int i = 0; i < 10; i++)
        {
            var newThread = new Thread(Client.ContatctServer);
            newThread.Start();
        }

    }

    public static void ContatctServer()
    {
        Random rnd = new Random();
        TcpClient socketForServer;
        try
        {
            socketForServer = new TcpClient("localHost", 12000);
        }
        catch
        {
            Console.WriteLine(
                "Failed to connect to server at {0}:12000", "localhost");
            return;
        }

            NetworkStream networkStream = socketForServer.GetStream();
            StreamReader streamReader = new StreamReader(networkStream);
        StreamWriter streamWriter = new StreamWriter(networkStream);

        try
        {


           // Console.WriteLine("Please enter a command in form (r/b,id,num");
            string myInstruction = RandomInstruction(rnd);
            streamWriter.WriteLine(myInstruction);

            // Console.WriteLine("Client Message");
            Console.WriteLine("Wrote " + myInstruction + " to Server.");
            streamWriter.Flush();
           string outputString = streamReader.ReadLine();
            Console.WriteLine("Here is the Servers response:");

            Console.WriteLine(outputString);
           // outputString = streamReader.ReadLine();
        }
        catch
        {
            Console.WriteLine("Exception reading from Server");
        }
        finally
        {
            // tidy up
            networkStream.Close();
            Console.ReadLine();
        }
    }

总结一个更好且不那么普遍的问题,上面的代码中有什么东西可以表明我的线程在它们不应该的时候共享流吗?如果没有任何其他想法可以包含IOException?

0 个答案:

没有答案