我的服务器/监听器有ADD或没有耐力;什么是解毒剂或产品?
该应用程序充当套接字通信的两端。它似乎适用于第一条消息(我在textBox1中输入“Bla”,然后label1读取“Bla back atcha”,但它在后续消息中失败。我在我的开发机器上运行了一个应用程序实例,另一个实例(在其他计算机上重命名为包含“服务器”一词)。
我已经粘贴了下面的代码,并且错误的消息我第二次尝试发送消息(“因为目标机器主动拒绝它而无法建立连接10.24.93.110:51111").
当我在另一台机器上启动“Server”实例并在命令行中运行“netstat -a”时,它表示服务器机器正在侦听端口51111上的dev机器。
传递第一条消息后,显然收到并抛回,运行“netstat -a”仍显示与我的开发机器的连接,但该状态不再是LISTENING而是TIME_WAIT。
然后,我尝试传递另一条消息,我得到了错误的消息(下面的图表B)
附件A:来源
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Diagnostics;
namespace testSocketSendAndReceive_Nutshell
{
public partial class Form1 : Form
{
string sJerrysIPAddr = "10.24.31.110";
string sMyIPAddr = "10.24.31.128";
string sThisAppFileName = string.Empty;
bool bThisInstanceFunctionsAsServer = false;
internal static Form1 MainSocketPairForm = null;
public Form1()
{
InitializeComponent();
MainSocketPairForm = this;
}
private void Form1_Load(object sender, EventArgs e)
{
sThisAppFileName = System.Diagnostics.Process.GetCurrentProcess().ProcessName;
lblFileName.Text = sThisAppFileName;
// Client and Server code are here combined in one app; however, we want each instance to run as
// just one or the other, so (the .exe functioning as a Server should be renamed with the subString
// "Server" somewhere in the filename):
bThisInstanceFunctionsAsServer = sThisAppFileName.Contains("Server");
if (bThisInstanceFunctionsAsServer)
{
new Thread(Server).Start(); // Run server method concurrently.
Thread.Sleep(500); // Give server time to start.
}
btnSendMsg.Visible = !bThisInstanceFunctionsAsServer;
}
static void Client()
{
using (TcpClient client = new TcpClient(Form1.MainSocketPairForm.sJerrysIPAddr, 51111)) // err here second time
using (NetworkStream n = client.GetStream())
{
BinaryWriter w = new BinaryWriter(n);
w.Write(Form1.MainSocketPairForm.textBox1.Text.ToString());
w.Flush();
Form1.MainSocketPairForm.label1.Text = new BinaryReader(n).ReadString();
}
}
static void Server() // Handles a single client request, then exits.
{
TcpListener listener = new TcpListener(IPAddress.Any, 51111);
listener.Start(); //Only one usage of each socket address (protocol/network address/port) is normally permitted
// got the above err msg with an instance running and listening on jerry's machine
// continues to listen even after shut down...
using (TcpClient c = listener.AcceptTcpClient())
using (NetworkStream n = c.GetStream())
{
string msg = new BinaryReader(n).ReadString();
BinaryWriter w = new BinaryWriter(n);
w.Write(msg + " back atcha!");
w.Flush(); // Must call Flush because we're not disposing the writer.
}
listener.Stop();
}
private void button1_Click(object sender, EventArgs e)
{
Client();
}
private void button2_Click(object sender, EventArgs e)
{
Close();
}
}
}
EXHIBIT B:完整错误消息
System.Net.Sockets.SocketException未处理 消息=“无法建立连接,因为目标计算机主动拒绝它10.24.93.110:51111” 来源=“系统” 错误码= 10061 NativeErrorCode = 10061 堆栈跟踪: 在System.Net.Sockets.TcpClient..ctor(String hostname,Int32 port) 在testSocketSendAndReceive_Nutshell.Form1.Client()中 C:\ testSocketSendAndReceive_Nutshell \ testSocketSendAndReceive_Nutshell \ Form1.cs:第57行 at testSocketSendAndRendive_Nutshell.Form1.button1_Click(Object sender,EventArgs e)位于C:\ testSocketSendAndReceive_Nutshell \ testSocketSendAndReceive_Nutshell \ Form1.cs:第90行,位于System.Windows.Forms.Control.OnClick(EventArgs e) 在System.Windows.Forms.Button.OnClick(EventArgs e) 在System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent) 在System.Windows.Forms.Control.WmMouseUp(消息& m,MouseButtons按钮,Int32点击) 在System.Windows.Forms.Control.WndProc(消息& m) 在System.Windows.Forms.ButtonBase.WndProc(消息& m) 在System.Windows.Forms.Button.WndProc(消息& m) 在System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m) 在System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m) 在System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd,Int32 msg,IntPtr wparam,IntPtr lparam) 在System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg) 在System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID,Int32 reason,Int32 pvLoopData) 在System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32原因, ApplicationContext context) 在System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason,ApplicationContext) 上下文) 在System.Windows.Forms.Application.Run(Form mainForm) 在testSocketSendAndReceive_Nutshell.Program.Main()中 C:\ testSocketSendAndReceive_Nutshell \ testSocketSendAndReceive_Nutshell \ Program.cs:第18行 在System.AppDomain._nExecuteAssembly(Assembly assembly,String [] args) 在System.AppDomain.ExecuteAssembly(String assemblyFile,Evidence assemblySecurity,String [] args) 在Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() 在System.Threading.ThreadHelper.ThreadStart_Context(对象状态) 在System.Threading.ExecutionContext.Run(ExecutionContext executionContext,ContextCallback回调, 对象状态) 在System.Threading.ThreadHelper.ThreadStart() InnerException:
答案 0 :(得分:3)
查看服务器代码开头的注释
static void Server() // Handles a single client request, then exits.
这是完全正确的 - 你打电话给AcceptTcpClient
一次,回应,然后关闭听众。那只会处理一个连接。如果你想要它处理多个连接,你需要循环 - 很可能在循环并再次接受之前将每个TCP客户端交给一个单独的线程。
答案 1 :(得分:2)
您对Server()
方法的评论会回答您自己的问题:
// Handles a single client request, then exits.
读完第一个字符串后,调用listener.Stop()
然后从函数返回,以便线程退出。如果您希望服务器为后续请求保持活跃状态,那么您将不得不采用某种循环方式。
答案 2 :(得分:2)
在您的服务器上,您在收到第一条消息后正在处理客户端。
如果要保持TCP连接处于活动状态,则需要在服务器方法中保存TCP客户端。然后你可以使用像client.GetStream().Read()
这样的方法来读取客户端的数据。请注意,此方法将阻止,直到您从流中收到消息。
为了处理n个请求,你必须做一些循环:
while(true) {
string msg = client.GetStream().Read();
// do something with the message
}
还有一些异步方法可以让您在另一个线程上执行这些操作。查看流上的BeginRead()
方法。
答案 3 :(得分:1)
发送响应后需要调用你client.Close()
。还需要循环服务器的接受逻辑:
var shouldExit == false;
while (!shouldExit)
using (TcpClient c = listener.AcceptTcpClient())
{
using (NetworkStream n = c.GetStream())
{
string msg = new BinaryReader(n).ReadString();
if (msg == "exit")
// Client told us to exit...
shouldExit = true;
BinaryWriter w = new BinaryWriter(n);
w.Write(msg + " back atcha!");
w.Flush(); // Must call Flush because we're not disposing the writer.
}
}
这就是文档中的示例:http://msdn.microsoft.com/en-us/library/system.net.sockets.tcplistener.aspx