C#.Net套接字服务器客户端
我对C#中的.Net套接字有点问题。 我编写了一个客户端和一个使用TCP的服务器 当客户端打开时,它向服务器发送握手。服务器以其状态(clientexists、clientaccepted,…)进行应答。在此之后,应用程序发送一个getdata请求,放弃连接并侦听服务器的“响应”。现在,服务器与客户端建立连接,并发送客户端需要的所有数据 代码和其他一切都正常,但问题是: 在我们公司的testserver上,它可以正常工作,而在live server上,只有握手可以正常工作。之后,客户端不再接收任何数据。两台服务器上的服务器应用程序相同 我认为问题是由防火墙引起的(服务器想要建立到客户端的tcp连接->不好),但是系统管理员说没有防火墙可以阻止它 现在,我正在寻找一种“便宜”的解决方案,它不需要花费太多的时间和代码更改。如果有人知道如何从理论上解决这个问题,那就太好了 顺便说一句:除了运行服务器应用程序,我不允许在实时服务器上执行任何操作。我无法在此服务器上调试 我不能发布我所有的代码,但如果你需要查看它的特定部分,请索取 ---编辑--- 客户机-服务器通信 1) 客户端启动C#.Net套接字服务器客户端,c#,.net,sockets,tcp,C#,.net,Sockets,Tcp,我对C#中的.Net套接字有点问题。 我编写了一个客户端和一个使用TCP的服务器 当客户端打开时,它向服务器发送握手。服务器以其状态(clientexists、clientaccepted,…)进行应答。在此之后,应用程序发送一个getdata请求,放弃连接并侦听服务器的“响应”。现在,服务器与客户端建立连接,并发送客户端需要的所有数据 代码和其他一切都正常,但问题是: 在我们公司的testserver上,它可以正常工作,而在live server上,只有握手可以正常工作。之后,客户端不再接收任
客户端发送握手(新tcp连接)
2) 服务器验证握手并保存IP
服务器以其客户端状态(相同的tcp连接)进行响应
3) 客户端确认此响应并放弃此连接
客户端发送getdata请求(新tcp连接)
客户端也放弃此tcp连接
4) 服务器接收getdata请求并在主数据库中收集所需的数据
服务器将所有收集的数据发送到客户端(多个tcp连接)
5) 客户机接收所有数据并在其GUI中显示(多个tcp连接,通过使用AutoResetEvents和要发送的套接字计数来保持数据的顺序) 这是我的代码的主要部分。这不是最好的,但我想这是我写的。第一步、第二步和第三步按预期进行。数据处理也很好。 我忘记提到的另一件事是,解决方案使用了两个端口“16777”和“16778”。一个接收/收听,一个发送。 我的代码是基于MSDN的异步和 发送握手(和getdata请求) 服务器侦听器
public void StartListening()
{
listener = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
// Bind the socket to the local endpoint and listen for incoming connections.
try
{
listener.Bind(localEndPoint);
listener.Listen(System.Int32.MaxValue);
while (true)
{
// Set the event to nonsignaled state.
allDone.Reset();
// Start an asynchronous socket to listen for connections.
listener.BeginAccept(
new AsyncCallback(AcceptCallback),
listener);
// Wait until a connection is made before continuing.
allDone.WaitOne();
}
}
catch (Exception e)
{
//--
}
}
public void AcceptCallback(...);
public void ReadCallback(...);
套接字发送
private void Send(Socket handler, String data)
{
Socket t = RetrieveSocket(((IPEndPoint)handler.RemoteEndPoint).Address);
// Convert the string data to byte data using ASCII encoding.
byte[] byteData = Encoding.UTF8.GetBytes(data);
// Begin sending the data to the remote device.
t.BeginSend(byteData, 0, byteData.Length, 0,
new AsyncCallback(SendCallback), t);
}
套接字发送所有数据部分(对getdata请求的应答| socToHandle应该是getdata请求上一个连接的套接字)
查看我的旧代码,我有一个想法=>
我是否可以通过更改以下内容通过同一连接发送所有内容:
套接字t=RetrieveSocket(((IPEndPoint)handler.RemoteEndPoint.Address)
(创建新连接)到使用相同连接的对象?
如果那样行得通,我怎么做?
客户端的侦听器部分还会接收单个数据包吗?服务器及其环境已配置为正确处理传入请求。客户端通常位于路由器后面,默认情况下,这会使它们无法接收来自网络外部的传入连接(这是一件好事) 要启用传入连接,可以将路由器配置为将特定端口号的所有请求转发到计算机。不过,您网络上的其他人都无法运行该客户端 这就是为什么在典型的多客户端单服务器环境中,客户端进行所有连接,只有服务器需要对网络环境进行任何更改
我不知道您为什么选择从服务器端连接到客户端,但我强烈建议不要这样做-任何使用此机制的廉价解决方案最终可能会非常昂贵。假设系统管理员撒谎。尝试在端口上运行服务器并使用测试连接。上载尝试ping客户端IP的代码版本。另外,双方都应该经常测试防火墙/连接问题并记录它们。你不必向我们展示“我所有的代码”——事实上,这会适得其反。对您有用的是创建一个。TCP实现中的一个常见错误与接收流的处理有关。接收过程必须考虑到发送请求可以在不同的块中接收。您需要使用长度值方法或分隔符(例如STX和ETX)封装发送数据。由于一个较小的网络路由问题,您似乎已经放弃了。只要解决这个问题。显然,代码在您的机器上工作。(不过,结束这个问题,因为这里没有足够的信息来回答。这似乎是一个路由问题,仅此而已。)我很确定您的问题在
ReadCallback
代码中。看起来您忽略了消息帧(您没有发送字符串的长度,也没有终止符;但是如果没有ReadCallback
code),就无法确定TCP是一个流,而不是一堆消息。Windows处理本地TCP的方式完全不同,这通常会导致应用程序在本地主机上工作(大部分)正常,但在实际网络连接上测试时完全失败。网络交流会带来更多的问题。谢谢你的建议,我以后肯定会这么做,但我现在没有时间重写我所有的代码。任何客户端和服务器之间都没有路由器,只有第2层交换机。
private void Send(Socket handler, String data)
{
Socket t = RetrieveSocket(((IPEndPoint)handler.RemoteEndPoint).Address);
// Convert the string data to byte data using ASCII encoding.
byte[] byteData = Encoding.UTF8.GetBytes(data);
// Begin sending the data to the remote device.
t.BeginSend(byteData, 0, byteData.Length, 0,
new AsyncCallback(SendCallback), t);
}
private void SendAllData(Socket socToHandle, string PakContent)
{
#region IsThereADatetime? //Resolve a given datetime
#region GiveClientNumberOfPackets //Send the client info about how much he has to receive (See line below)
Send(socToHandle, "ALERT#TASKCOUNT;OPT-" + GetBestDate(dateStart) + EndSocket);
#region #SendResouces
#region #SendGroups
#region #SendTasks
}