【发布时间】:2015-09-29 16:29:10
【问题描述】:
我用 C# 编写了一个简单的服务器和客户端代码。客户端一连接上,服务器就会向客户端一一发送欢迎信息、文件大小和字符串,客户端会显示出来。客户端会将字符串转换为字符串数组并显示出来。之后,客户端将向服务器发送一个 id,服务器将显示它。但问题是,客户端没有正确显示。当我在运行服务器后运行客户端程序时,它显示以下内容,而它应该在一行中显示每条消息。
welcome1.cpp,.jpg,.png
此外,在客户端,我为显示转换后的字符串数组而编写的行根本不起作用,此后的行也没有执行。似乎,代码挂起。我已经在我的代码中标记了它。我的示例代码如下:
服务器:
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Text;
namespace server
{
class Program
{
static void Main(string[] args)
{
// Listen on port 1234.
try
{
TcpListener tcpListener = new TcpListener(IPAddress.Any, 1234);
tcpListener.Start();
byte[] data = new byte[1024];
// Infinite loop to connect to new clients.
while (true)
{
// Accept a TcpClient
TcpClient tcpClient = tcpListener.AcceptTcpClient();
NetworkStream ns = tcpClient.GetStream();
//sending welcome message
string welcome = "welcome";
ns.Write(Encoding.ASCII.GetBytes(welcome), 0, welcome.Length);
ns.Flush();
//sending file size
string fsize = "1";
ns.Write(Encoding.ASCII.GetBytes(fsize), 0, fsize.Length);
ns.Flush();
//sending extensions
string[] extensions = { ".cpp", ".jpg", ".png" };
string str = string.Join(",", extensions);
Console.WriteLine(str);
ns.Write(Encoding.ASCII.GetBytes(str), 0, str.Length);
ns.Flush();
//receiving id
int recv = ns.Read(data, 0, data.Length);
string id = Encoding.ASCII.GetString(data, 0, recv);
Console.WriteLine(id);
}
}
catch (Exception e)
{
Console.Write(e.Message);
}
Console.Read();
}
}
}
客户:
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Text;
namespace client
{
class Program
{
static void Main(string[] args)
{
try
{
TcpClient tcpClient = new TcpClient("127.0.0.1", 1234);
NetworkStream ns = tcpClient.GetStream();
byte[] data = new byte[1024];
StreamWriter sWriter = new StreamWriter(tcpClient.GetStream());
//receiving welcome message
int recv = ns.Read(data, 0, data.Length);
string message = Encoding.ASCII.GetString(data, 0, recv);
Console.WriteLine(message);
//receive filesize
int recv2 = ns.Read(data, 0, data.Length);
string message2 = Encoding.ASCII.GetString(data, 0, recv2);
Console.WriteLine(message2);
//receiving extensions
int recv1 = ns.Read(data, 0, data.Length);
string message1 = Encoding.ASCII.GetString(data, 0, recv1);
Console.WriteLine(message1);
var array2 = message1.Split(',');
foreach (string s in array2) //from this line the program isn't working
{
Console.WriteLine(s);
}
string input = Console.ReadLine();
ns.Write(Encoding.ASCII.GetBytes(input), 0, input.Length);
ns.Flush();
}
catch (Exception e)
{
Console.Write(e.Message);
}
Console.Read();
}
}
}
代码有什么问题?
【问题讨论】:
-
如果您在
var array2 ...设置断点,您将看到该字符串消息可能包含来自服务器的所有数据。 Tcp 连接就像一根水管,你输入的每一个数据都从另一端出来。收集所有数据和处理是您的工作。不能保证 1 个 ns.Write 等于 1 个 ns.Read。 -
@togocoder 我认为代码已经挂在
int recv2,因为所有数据都将由第一个ns.read接收,并且上述行中的第二个调用被阻塞,因为没有更多数据存在。 -
是的,你是对的。
ns.Read将阻塞直到有数据或连接关闭