用于发送字节数组和字符串的流(用于网络)
Posted
技术标签:
【中文标题】用于发送字节数组和字符串的流(用于网络)【英文标题】:Stream for sending byte-arrays and strings (for network) 【发布时间】:2014-03-14 21:52:30 【问题描述】:我正在寻找包含以下内容的 Streamclass: - 一种发送/接收字节数组的方法 - 一种发送/接收字符串的方法
我发现的唯一类是 NetworkStream。但是 NetworkStream-Class 的缺点是,如果我想发送一个字符串,我必须先将这个字符串转换为一个字节数组并发送这个字节数组,因为没有直接发送字符串的方法。 而另一方面,像 Streamwriter 这样的类有发送/接收字符串的方法,但没有发送/接收字节数组的方法。
如果我尝试像这样组合这两个 Streamclass:
TcpClient clientConnection = new TcpClient();
NetworkStream nws = clientConnection.GetStream();
StreamWriter sw = new StreamWriter(nws);
sw.writeLine("ABC");
sw.Flush();
nws.Write(byteArray, 0, lengthToSend);
我得到了很多奇怪的错误(比如 byteArray 不会在另一边完全接收),因为我在这里以两种不同的方式使用同一个流。
那么,我必须为我的计划使用 NetworkStream-Class 还是存在更好的方法?
【问题讨论】:
您的问题是什么?如果是关于您当前的代码,请阅读this。如果是关于 "any better way" ,那么可以,但过于宽泛,无法在答案中发布。 " 但是 NetworkStream-Class 的缺点是,如果我想发送一个字符串,我必须先将这个字符串转换成一个字节数组并发送这个字节数组“所以写一个包装器和继续吗? 【参考方案1】:我遇到了同样的问题,关键是对方不知道你发送的是什么字节数组或字符串,所以我所做的是在处理严重的服务器/客户端应用程序时为每个 msg 设置一个标题,因为你会有多个数据(用户信息、请求信息、回复信息等)
我正在使用 streamwriter 发送和 streamreader 接收,但我也使用线程 只要客户端连接,连接就会保持打开状态,所以我声明它们一次
这是我的代码的完整示例
public class Client
private StreamWriter swSender;
private StreamReader srReceiver;
private TcpClient tcpServer;
private Thread thrMessaging;
private string UserName = "UK";
private byte Tries = 0;
private bool Connected = false;
public void Connect()
if (!Connected)
IPAddress[] localIPs = Dns.GetHostAddresses(Dns.GetHostName());
string User = localIPs[0].ToString();
string ServIP = "127.0.0.1";//change this to your server ip
InitializeConnection(ServIP, User);
else
CloseConnection("Disconnected at user's request.");
private void InitializeConnection(string ServIp, string User)
IPAddress ipAddr = IPAddress.Parse(ServIp);
tcpServer = new TcpClient();
try
tcpServer.Connect(ipAddr, 1986);//change that 1986 to your server port
catch
if (Connected) CloseConnection("");
MessageBox.Show("Connecteing to " + ServIp + "\r\nServer is Down ... Try nomber " + Tries); return;
Connected = true;
UserName = User;
swSender = new StreamWriter(tcpServer.GetStream());
swSender.WriteLine(User);
swSender.Flush();
thrMessaging = new Thread(new ThreadStart(ReceiveMessages));
thrMessaging.Start();
private void ReceiveMessages()
srReceiver = new StreamReader(tcpServer.GetStream());
string ConResponse = srReceiver.ReadLine();
if (ConResponse[0] == '1')
else
string Reason = "Not Connected: ";
Reason += ConResponse.Substring(2, ConResponse.Length - 2);
return;
while (Connected)
try
string NewMsg = srReceiver.ReadLine();
if (NewMsg != null && NewMsg != "")
PacketHandler.HandlePacket(NewMsg, this);
catch
public void CloseConnection(string Reason)
try
Connected = false;
swSender.Close();
srReceiver.Close();
tcpServer.Close();
catch
public void SendMessage(string Msg)
if (Msg.Length >= 1)
try
Tries++;
swSender.WriteLine(Msg);
swSender.Flush();
Tries = 0;
catch
if (Tries < 5)
try
CloseConnection("No connection made");
Connect();
catch
SendMessage(Msg);
else MessageBox.Show("Connecting to server faild for 5 tries"); Tries = 0;
然后在数据包处理程序中,我会检查客户端收到的数据类型
类似的东西
public static void HandlePacket(string MsgRec, Client Client)
string[] Info = MsgRec.Split('|');
string Type = Info[0];
if (Type == "")
return;
string subtype = Info[1];
int TLen = Type.Length + subtype.Length + 2;
string Data = MsgRec.Remove(0, TLen);//this is the main data the server sent
ushort PacketType = ushort.Parse(Type);
ushort SubType = ushort.Parse(subtype);
switch ((Structs.PacketType)PacketType)
case Structs.PacketType.Login:
//do your stuff here
break
case Structs.PacketType.Image:
//convert the Data back to byte array then get the image out from it
break
case Structs.PacketType.ByteArray:
//convert the Data back to byte array
break
我知道它有点乱,而且不是完美的方法,但它对我有用 并记住,在发送某些内容时,您需要添加数据包类型和子类型,或者如果您做一些简单的事情,则只需添加带有任何拆分器的任何标头
最后:我认为如果你发送小数据包长度,使用套接字和数据包会容易得多
【讨论】:
以上是关于用于发送字节数组和字符串的流(用于网络)的主要内容,如果未能解决你的问题,请参考以下文章