C# 我的服务器/侦听器缺乏真正的勇气
我的服务器/侦听器有额外或没有耐力;解药或前药是什么 应用程序充当套接字通信的两端。对于第一条消息(我在textBox1中输入“Bla”,然后label1读取“Bla back atcha”),它似乎工作正常,但在后续消息中失败。我有一个应用程序实例在我的开发机器上运行,另一个实例(重命名为包含单词“Server”)在另一台机器上运行 我已经粘贴了下面的代码,以及第二次尝试发送消息时得到的err msg(“无法建立连接,因为目标机器主动拒绝了它10.24.93.110:51111”) 当我在另一台机器上启动“Server”实例并在命令行中运行“netstat-a”时,它表示服务器正在端口51111上侦听我的dev机器 在第一条消息被传递并被接收和抛出后,运行“netstat-a”仍然显示与我的开发机器的连接,但该状态不再是侦听,而是等待时间 然后,我尝试传递另一条消息,得到err msg(下面的附件B) 附件A:资料来源C# 我的服务器/侦听器缺乏真正的勇气,c#,sockets,C#,Sockets,我的服务器/侦听器有额外或没有耐力;解药或前药是什么 应用程序充当套接字通信的两端。对于第一条消息(我在textBox1中输入“Bla”,然后label1读取“Bla back atcha”),它似乎工作正常,但在后续消息中失败。我有一个应用程序实例在我的开发机器上运行,另一个实例(重命名为包含单词“Server”)在另一台机器上运行 我已经粘贴了下面的代码,以及第二次尝试发送消息时得到的err msg(“无法建立连接,因为目标机器主动拒绝了它10.24.93.110:51111”) 当我在另一
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();
}
}
}
附件B:完整错误消息
System.Net.Sockets.SocketException未处理
Message=“无法建立连接,因为目标计算机主动拒绝它10.24.93.110:51111”
Source=“系统”
错误代码=10061
NativeErrorCode=10061
堆栈跟踪:
位于System.Net.Sockets.TcpClient..ctor(字符串主机名,Int32端口)
在中的TestSocketSendReceive_Nutshell.Form1.Client()处
C:\testSocketSendAndReceive\u Nutshell\testSocketSendAndReceive\u Nutshell\Form1.cs:第57行
在testSocketSendAndReceive_Nutshell.Form1.button1_单击C:\testSocketSendAndReceive_Nutshell\testSocketSendAndReceive_Nutshell\Form1.cs中的(对象发送者,事件参数e):System.Windows.Forms.Control.OnClick(事件参数e)的第90行
在System.Windows.Forms.Button.OnClick(EventArgs e)中
在System.Windows.Forms.Button.OnMouseUp(MouseEventArgs-mevent)上
在System.Windows.Forms.Control.WmMouseUp(Message&m、MouseButtons按钮、Int32单击)
位于System.Windows.Forms.Control.WndProc(Message&m)
位于System.Windows.Forms.ButtonBase.WndProc(Message&m)
在System.Windows.Forms.Button.WndProc(Message&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.UnsafentiveMethods.DispatchMessageW(MSG&MSG)中
位于System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafentiveMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID、Int32 reason、Int32 pvLoopData)
在System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32原因,
应用程序上下文(上下文)
位于System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason,ApplicationContext
(上下文)
在System.Windows.Forms.Application.Run(Form mainForm)中
在中的testsocketsend和receive_Nutshell.Program.Main()处
C:\testSocketSendAndReceive\u Nutshell\testSocketSendAndReceive\u Nutshell\Program.cs:第18行
位于System.AppDomain.\u nexecutestAssembly(程序集,字符串[]args)
位于System.AppDomain.ExecuteAssembly(字符串汇编文件、证据汇编安全性、字符串[]args)
在Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()上
位于System.Threading.ThreadHelper.ThreadStart\u上下文(对象状态)
在System.Threading.ExecutionContext.Run(ExecutionContext ExecutionContext,ContextCallback回调,
对象状态)
位于System.Threading.ThreadHelper.ThreadStart()处
内部异常:
发送响应后,需要调用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.
}
}
这都在文档中的示例中:您需要在发送响应后调用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.
}
}
这些都在文档中的示例中:查看服务器代码开头的注释
static void Server() // Handles a single client request, then exits.
这是完全正确的-您调用
AcceptCpcClient
一次,做出响应,然后关闭侦听器。这将只处理一个连接。如果您希望它处理多个连接,您需要循环-很可能在循环并再次接受之前,将每个TCP客户端交给一个单独的线程。不要在服务器代码的开头添加注释
static void Server() // Handles a single client request, then exits.
这是完全正确的-您调用
AcceptCpcClient
一次,做出响应,然后关闭侦听器。这将只处理一个连接。如果您希望它处理多个连接,您需要循环-很可能在循环并再次接受之前,将每个TCP客户端交给一个单独的线程。Server()
方法上的注释回答了您自己的问题:
// Handles a single client request, then exits.
读取第一个字符串后,调用
listener.Stop()
,然后从函数返回,因此线程退出。如果希望服务器在后续请求中保持活动状态,则必须合并某种循环。您对server()
方法的评论回答了您自己的问题:
// Handles a single client request, then exits.
读取第一个字符串后,调用listener.Stop(),然后从函数返回,因此线程将退出。如果希望服务器在后续请求中保持活动状态,则必须合并某种循环。在服务器上,您将在收到第一条消息后处理客户端 如果要保持TCP连接处于活动状态,则需要将TCP客户端保存在服务器方法中。然后可以使用
client.get之类的方法