TcpClient:在未连接的套接字上不允许操作 - C# 4.5
TcpClient: Operation not allowed on non-connected Sockets - C# 4.5
为什么下面的代码给出下面的异常?
The operation not allowed on non-connected sockets.
This link 表示:
You gotta Connect()
before you can get the NetworkStream
.
The documentation is usually pretty good for this kinda stuff. Under
Exceptions in the help for GetStream
, you'll see:
InvalidOperationException
: The TcpClient
is not connected to a remote host.
在这里,我的客户也在做同样的事情。
所以,出了什么问题?
客户代码:
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);
}
}
}
}
看起来您的服务器端实现在 doRequest
之后关闭套接字,因此对于客户端,您需要为每个输入创建新的 TcpClient 实例。或者重写服务器端代码以保持套接字打开。
为什么下面的代码给出下面的异常?
The operation not allowed on non-connected sockets.
This link 表示:
You gotta
Connect()
before you can get theNetworkStream
.The documentation is usually pretty good for this kinda stuff. Under Exceptions in the help for
GetStream
, you'll see:
InvalidOperationException
: TheTcpClient
is not connected to a remote host.
在这里,我的客户也在做同样的事情。
所以,出了什么问题?
客户代码:
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);
}
}
}
}
看起来您的服务器端实现在 doRequest
之后关闭套接字,因此对于客户端,您需要为每个输入创建新的 TcpClient 实例。或者重写服务器端代码以保持套接字打开。