TcpClient: Операция не разрешена для неподключенных сокетов - C# 4.5 - PullRequest
0 голосов
/ 23 февраля 2020

Почему следующий код дает следующее исключение?

The operation not allowed on non-connected sockets.

Эта ссылка говорит, что :

Вы должны Connect(), прежде чем сможете получить NetworkStream.

Документация обычно довольно хороша для такого рода вещей. В разделе Исключения в справке для GetStream вы увидите:

InvalidOperationException: TcpClient не подключен к удаленному хосту.

Здесь мой клиент делает то же самое.

Итак, что не так?

enter image description here

Код клиента:

using System;
using System.Net.Sockets;
using System.IO;

namespace WhoIsClientNamespace
{
    public class WhoIsClient
    {
        static void Main()
        {
            Console.Title = "Client";
            string kbInput;
            try
            {
                TcpClient client = new TcpClient();
                client.Connect("localHost", 43);
                Console.WriteLine("Client started...");
                Console.WriteLine("Enter command to the server!");
                Console.WriteLine(" # ");

                while (true)
                {
                    kbInput = Console.ReadLine();
                    Console.WriteLine(kbInput);

                    if ("exit" == kbInput)
                    {
                        Console.WriteLine("while loop exited!");
                        break;
                    }

                    string[] args = kbInput.Split(' ');

                    if (args.Length < 1)
                    {
                        Console.WriteLine("Provide more than one Args");
                    }
                    else if (args.Length == 1)
                    {
                        StreamWriter sw = new StreamWriter(client.GetStream());
                        StreamReader sr = new StreamReader(client.GetStream());
                        string str = kbInput;
                        sw.WriteLine(kbInput);
                        sw.Flush();
                        Console.WriteLine(kbInput[0] + " is " + sr.ReadToEnd());
                        return;
                    }
                    else if (args.Length > 1)
                    {
                        StreamWriter sw = new StreamWriter(client.GetStream());
                        StreamReader sr = new StreamReader(client.GetStream());
                        string str = kbInput;
                        sw.WriteLine(str);
                        sw.Flush();
                        //Console.WriteLine(kbInput[0] + " location changed to be " + args[1]);
                        sw.Close();
                    }
                    else
                    {
                        Console.WriteLine("Invalid args ");
                    }
                }                
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }

            Console.WriteLine("Client exits!");
        }
    }
}

Код сервера:

using System;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Collections.Generic;

namespace WhoIsServerNamespace
{
    public class WhoIsServer
    {
        static Dictionary<string, string> 
            _locationsDictionary = new Dictionary<String, String>();
        static void Main(string[] args)
        {
            Console.Title = "Server";
            runServer();
        }
        static void runServer()
        {
            TcpListener listener;
            Socket connection;
            NetworkStream socketStream;
            try
            {
                listener = new TcpListener(IPAddress.Any, 43);
                listener.Start();

                Console.WriteLine("server started listening");

                while (true)
                {
                    connection = listener.AcceptSocket();
                    socketStream = new NetworkStream(connection);
                    Console.WriteLine("Connection Received");
                    doRequest(socketStream);
                    socketStream.Close();
                    connection.Close();
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("Exception:" + e.ToString());
            }
        }

        static void doRequest(NetworkStream socketStream)
        {
            try
            {
                StreamWriter sw = new StreamWriter(socketStream);
                StreamReader sr = new StreamReader(socketStream);
                String strClientInput = sr.ReadLine();
                Console.WriteLine("Respond Received:" + strClientInput);
                String[] clientInputsSplitted = strClientInput.Split(new char[] { ' ' }, 2);
                String name;
                String location;

                if (clientInputsSplitted.Length < 1)
                {
                    Console.WriteLine("Too little words was inputted");
                }
                else if (clientInputsSplitted.Length == 1)
                {/* when we receive only one command-string from client,
                    that is considered as the name of the server.
                    So, the server returns its corresponding location. */
                    name = clientInputsSplitted[0];//obtain the name from the client-command-string.
                    if (_locationsDictionary.ContainsKey(name))//Is the [name] in the dictionary?
                    {
                        Console.WriteLine(name + "'s location is :"+ _locationsDictionary[name]);
                        sw.WriteLine(_locationsDictionary[name]);//return location to the client.
                    }
                    else
                    {
                        Console.WriteLine("Error: [name] not found in the dictionary");
                        sw.WriteLine("Error: [name] not found in the dictionary");
                    }
                    sw.Flush();
                }
                else if (clientInputsSplitted.Length == 2)
                {/* when we receive two command-string from client,
                    that is considered as the (name, location) pair of the server.
                    So, the server returns its corresponding location. */
                    name = clientInputsSplitted[0];
                    location = clientInputsSplitted[1];

                    if (_locationsDictionary.ContainsKey(name))
                    {
                        _locationsDictionary[name] = location;
                        Console.WriteLine("(" + name + "," + location + ") updated");
                        sw.WriteLine("("+name +","+ location +") updated");
                    }
                    else
                    {
                        _locationsDictionary.Add(name, location);
                        Console.WriteLine("(" + name + "," + location + ") added");
                        sw.WriteLine("(" + name + "," + location + ") added");
                    }
                    sw.Flush();
                }

                if (strClientInput.Contains("-h0"))
                {
                    Console.WriteLine("Is                ok");
                    sw.WriteLine("Is ok");
                }
                else if (strClientInput.Contains("-h9"))
                {
                    Console.WriteLine("Hey you're progressing");
                    sw.WriteLine("Hey you're progressing");
                }
                else if (strClientInput.Contains("-h1"))
                {
                    Console.WriteLine("We're Done");
                    sw.WriteLine("We're Done");
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("Something went wrong");
                Console.WriteLine(e.Message);
            }
        }
    }
}

1 Ответ

0 голосов
/ 23 февраля 2020

Похоже, что ваша реализация на стороне сервера закрывает сокет после doRequest, поэтому для клиентской стороны вам нужно создать новый экземпляр TcpClient для каждого входа. Или перепишите код на стороне сервера, чтобы оставить сокет открытым.

...