【发布时间】:2012-09-21 02:14:02
【问题描述】:
客户代码:
TcpClient client = new TcpClient();
NetworkStream ns;
private void Form1_Load(object sender, EventArgs e)
{
try
{
client.Connect("127.0.0.1", 560);
ns = client.GetStream();
byte[] buffer = ReadFully(ns, client.Available);
//working with the buffer...
}
catch
{
//displaying error...
}
}
public static byte[] ReadFully(NetworkStream stream , int initialLength)
{
// If we've been passed an unhelpful initial length, just
// use 32K.
if (initialLength < 1)
{
initialLength = 32768;
}
byte[] buffer = new byte[initialLength];
long read = 0;
int chunk;
while ((chunk = stream.Read(buffer, (int)read, buffer.Length - (int)read)) > 0)
{
read += chunk;
// If we've reached the end of our buffer, check to see if there's
// any more information
if (read == buffer.Length)
{
int nextByte = stream.ReadByte();
// End of stream? If so, we're done
if (nextByte == -1)
{
return buffer;
}
// Nope. Resize the buffer, put in the byte we've just
// read, and continue
byte[] newBuffer = new byte[buffer.Length * 2];
Array.Copy(buffer, newBuffer, buffer.Length);
newBuffer[read] = (byte)nextByte;
buffer = newBuffer;
read++;
}
}
// Buffer is now too big. Shrink it.
byte[] ret = new byte[read];
Array.Copy(buffer, ret, read);
return ret;
}
服务器代码:
private static TcpListener tcpListener;
private static Thread listenThread;
private static int clients;
static void Main(string[] args)
{
tcpListener = new TcpListener(IPAddress.Any, 560);
listenThread = new Thread(new ThreadStart(ListenForClients));
listenThread.Start();
}
private static void ListenForClients()
{
tcpListener.Start();
Console.WriteLine("Server started.");
while (true)
{
//blocks until a client has connected to the server
TcpClient client = tcpListener.AcceptTcpClient();
//create a thread to handle communication
//with connected client
Thread clientThread = new Thread(new ParameterizedThreadStart(HandleClientComm));
clientThread.Start(client);
}
}
private static void HandleClientComm(object client)
{
clients++;
TcpClient tcpClient = (TcpClient)client;
NetworkStream clientStream = tcpClient.GetStream();
ASCIIEncoding encoder = new ASCIIEncoding();
Console.WriteLine("Client connected. ({0} connected)", clients.ToString());
#region sendingHandler
byte[] buffer = encoder.GetBytes(AddressBookServer.Properties.Settings.Default.contacts);
clientStream.Write(buffer, 0, buffer.Length);
clientStream.Flush();
#endregion
}
从代码中可以看出,我正在尝试将AddressBookServer.Properties.Settings.Default.contacts(一个字符串,非空)发送到连接的客户端。
问题是有时(这是奇怪的部分)客户端收到字符串,有时它一直被阻止在 ns.Read 线上等待接收。
我尝试通过在ns.Read 之后的行上放置一个断点来进行调试,我发现当它不起作用时它永远不会到达该行,因此它不会收到服务器发送的消息。
我的问题:我该如何解决?
我的假设:服务器在客户端接收之前发送消息,因此客户端永远不会收到它。
【问题讨论】:
-
一方面,您的
Read通话中断。您假设您将一口气阅读整个内容,并且您忽略了返回值。你不应该做这两件事。 -
我是网络编程新手,能不能给个固定的代码和解释?
-
是的,就是这样。 “读取操作读取尽可能多的数据,最多为 size 参数指定的字节数。”至于修复它,如果不了解您的协议,这并不容易。客户端应该如何知道要读取多少数据?
-
我已经编辑了我的客户端代码,请看一下。要读取多少数据
client.Available应该告诉你,不是吗? -
不要使用 Available 来检测逻辑消息的结束。只有决定策略(异步与同步、缓冲区与进程等)才有用。如果您预期多条消息,则需要实施“框架”策略,通常是“换行终止”(用于文本)或“长度前缀”(用于二进制)
标签: c# tcp network-programming tcpclient networkstream