gpt4 book ai didi

c# - TcpClient 已连接但服务器未收到消息

转载 作者:行者123 更新时间:2023-12-03 11:59:11 34 4
gpt4 key购买 nike

服务器 :

public class TcpServer
{
private TcpListener tcpListener;
private static ManualResetEvent allDone = new ManualResetEvent(false);

public TcpServer(string url, int port)
{
tcpListener = new TcpListener(IPAddress.Parse(url), port);
pingMapper = new LightPingMapper();
}


public void Run()
{
tcpListener.Start();

Console.WriteLine("Server running");
while (true)
{
allDone.Reset();
tcpListener.BeginAcceptSocket(AcceptCallback, tcpListener);
Console.WriteLine("Accepting socket");
allDone.WaitOne();
}

Console.ReadLine();
}

private void AcceptCallback(IAsyncResult result)
{
try
{
allDone.Set();

var listener = (TcpListener) result.AsyncState;
var handler = listener.EndAcceptSocket(result);

StateObject state = new StateObject();
state.workSocket = handler;
handler.BeginReceive(state.buffer, 0, state.buffer.Length, 0, ReadCallback, state);
}
catch (Exception e)
{
Console.WriteLine($"Error accepting callback. {e.Message}");
}
}

private void ReadCallback(IAsyncResult asyncResult)
{
try
{
string content = string.Empty;
Console.WriteLine("Read data from socket");

StateObject state = (StateObject) asyncResult.AsyncState;
Socket handler = state.workSocket;

int bytesRead = handler.EndReceive(asyncResult);
if (bytesRead > 0)
{
state.sb.Append(Encoding.UTF8.GetString(state.buffer));
content = state.sb.ToString();
Console.WriteLine(content + " " + DateTime.Now);
}
}
catch (Exception e)
{
Console.WriteLine($"Error reading socket. {e.Message}");
}
}
}

class StateObject
{
// Client socket.
public Socket workSocket = null;
// Size of receive buffer.
public const int BufferSize = 256;
// Receive buffer.
public byte[] buffer = new byte[BufferSize];
// Received data string.
public StringBuilder sb = new StringBuilder();
}

客户:
public class TCPClientWrapper
{
private TcpClient tcpClient;
private readonly string address;
private readonly int port;

public TCPClientWrapper(string address, int port)
{
InitTcpClient();
this.address = address;
this.port = port;
}

public void SendMessage()
{
for(int i=0; i < 10; i++)
{
if (!SocketConnected())
{
TryConnect();
}

byte[] buffer = Encoding.UTF8.GetBytes("Hello");
tcpClient.Client.Send(buffer);
Thread.Sleep(60000);
}
}

private void TryConnect()
{
bool isConnected = false;
while (true)
{
try
{
InitTcpClient();

tcpClient.Connect(IPAddress.Parse(address), port);
if (SocketConnected())
{
Console.WriteLine("TcpClient, Connected");
isConnected = true;
break;
}
}
catch (Exception e)
{
Console.WriteLine("TcpClient, connection failed. Try to reconnect after 30 seconds, {0}", e.Message);
}
finally
{
if (!isConnected)
{
tcpClient.Close();
Thread.Sleep(30000);
}
}
}
}

private void InitTcpClient()
{
tcpClient = new TcpClient();
tcpClient.SendTimeout = 15;
}

private bool SocketConnected()
{
var s = tcpClient.Client;

if (!s.Connected)
return false;

bool part1 = s.Poll(1000, SelectMode.SelectRead);
bool part2 = s.Available == 0;
return !(part1 && part2);
}

}

问题是服务器只读取第一条消息,服务器没有收到每条下一条消息。 tcpClient 已连接,但服务器未收到任何消息。谁能建议我的代码有什么问题?

最佳答案

ReadCallback ,您不会开始下一次阅读 - 所以是的,您的代码只读取一次。

添加

handler.BeginReceive(state.buffer, 0, state.buffer.Length, 0, ReadCallback, state);

ReadCallback 的底部(当 bytesRead > 0 )应该工作。然而!您没有实现适当的框架,因此您应该对此非常谨慎。基于文本的协议(protocol)(像这样)的基本框架实现将使用某种行尾哨兵,并缓冲数据直到您看到行尾,然后处理该行。

在 TCP 上,您只能保证以正确的顺序获得正确的字节(或最终失败的套接字)- 不能保证在调用 Send 时获得相同的组合。对 Receive 的调用完全匹配就每个字节数而言。

关于c# - TcpClient 已连接但服务器未收到消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56124427/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com