C# 通过TCP发送大字符串-Windows Phone
我在Windows Phone上开发了一个简单的TCP客户端,如图所示 这正如期发挥作用 现在,我想通过这个客户端发送非常大的Base64字符串(用于传输图像)。 但是,当我尝试从此客户端发送Base64字符串时,我在服务器上只接收到字符串的一部分,因此我无法在服务器上生成整个图像 用于接收字符串的服务器端代码为:(已编辑) 编辑:现在代码部分已缩减为C# 通过TCP发送大字符串-Windows Phone,c#,windows-phone-7,tcp,base64,tcpclient,C#,Windows Phone 7,Tcp,Base64,Tcpclient,我在Windows Phone上开发了一个简单的TCP客户端,如图所示 这正如期发挥作用 现在,我想通过这个客户端发送非常大的Base64字符串(用于传输图像)。 但是,当我尝试从此客户端发送Base64字符串时,我在服务器上只接收到字符串的一部分,因此我无法在服务器上生成整个图像 用于接收字符串的服务器端代码为:(已编辑) 编辑:现在代码部分已缩减为 int k = s.Receive(b); 不好:它假设所有数据一次发送就完成了,这不是网络的工作方式 两种选择: 在字符串
int k = s.Receive(b);
不好:它假设所有数据一次发送就完成了,这不是网络的工作方式
两种选择:
- 在字符串的开头,包括它应该有多长
- 在字符串的末尾,有一个不会出现在消息中其他任何地方的结束符号(可能是null)
int k = s.Receive(b);
Console.WriteLine("\nRecieved...");
for (int i = 0; i < k; i++)
{
message += Convert.ToChar(b[i]);
Console.Write(Convert.ToChar(b[i]));
}
改为
while (true)
{
int k = s.Receive(b);
Console.WriteLine("\nRecieved...");
for (int i = 0; i < k; i++)
{
char bc = Convert.ToChar(b[i]); // This is a very wrong way of doing this but it works I guess meh.
if (bc == ' ')
{ // You've struck the end! Get out of this infinite loop!
goto endmyloop;
}
message += bc;
Console.Write(bc);
}
}
endmyloop:
result = client.Send(str + " ");
--Base64中永远不能有空格,因此将使用空格标记结束
请注意,如果客户端出错(并且由于某些奇怪的原因没有在末尾发送空格),此代码将永远被困在while循环中(零CPU使用无限等待)客户端能够发送大的Base64字符串?您确定没有在完成所有操作之前关闭客户端的套接字吗?我建议您使用Wireshark之类的工具来查看实际发送的数据。如果您认为客户端是问题所在,那么客户端的代码在哪里?Jon很可能是对的-TCP是“礼貌”协议,因此fire and forget与UDP不一样,断开连接事件可能会占用网络缓冲区。正确的方法是使用一个协议,在该协议中,服务器向客户端确认已接收到所有数据。在移动世界中,对协议进行大小健全性检查也可能有帮助。TCP通常(尝试)确保在完全处理断开连接之前所有数据都已通过(除非尚未完成数据接收的系统尝试发送)。非常感谢您的帮助。我尝试使用Windows简单TCP服务作为服务器(而不是我的),它工作得非常好。因此,很明显,问题出在服务器上。但是,你能不能帮我一个字符一个字符地读取字符串,而不是使用
int k=s.Receive(b)
,这样我就可以在循环中接收内容,并在收到字符串结尾(手动追加)时中断循环。你只需对当前代码进行一些小的编辑就可以实现。请参阅我的编辑答案上面。老实说,您现有的全部代码和其中的基本思想都存在严重缺陷。。。但在这里解释这一切是没有意义的。继续练习C#和阅读教程!我是C#的新手,经验不多,所以我可能会使用不好的做法!好吧,不管怎样,我已经试过了你在这里说的方法,但它不起作用。它在无限循环中运行(空间通过客户端发送,我使用简单的TCP服务作为服务器验证)。我认为问题的出现是因为整个流只在以下位置获取一次:intk=s.Receive(b)
在无限循环中,我们每次都会收到相同的东西(被截断的字符串),对吗?@shrayansharma-可以肯定的是,你能将OP的代码与我编写的确切代码结合使用来插入它,而不必自己更改它,并告诉我这是怎么回事吗?--同样假设TcpListener.Receive
与底层的Socket.Receive
执行相同的操作,它应该只返回相同的文本块两次,而相同的文本块发送了两次。我已经尝试按原样使用您的代码,但没有做任何更改。但它在一个无限循环中运行,可能是因为我们只在一个语句中接收到所有内容:intk=s.Receive(b)代码>。下面的while
循环只是读取我们存储在字节数组中的内容(如果您看到,我们只是读取循环中的字节数组)。因此问题在于语句:intk=s.Receive(b)代码>。不是在一个语句中接收所有信息,而是可以一个字符一个字符地接收吗?
int k = s.Receive(b);
Console.WriteLine("\nRecieved...");
for (int i = 0; i < k; i++)
{
message += Convert.ToChar(b[i]);
Console.Write(Convert.ToChar(b[i]));
}
while (true)
{
int k = s.Receive(b);
Console.WriteLine("\nRecieved...");
for (int i = 0; i < k; i++)
{
char bc = Convert.ToChar(b[i]); // This is a very wrong way of doing this but it works I guess meh.
if (bc == ' ')
{ // You've struck the end! Get out of this infinite loop!
goto endmyloop;
}
message += bc;
Console.Write(bc);
}
}
endmyloop:
result = client.Send(str);
result = client.Send(str + " ");