winphone|wp7.5|wp8|socket通讯|TCP|循环接收多包数据修改|能用
最近同事开发wp应用,通讯tcp,找到官网例子,由于服务端是我原来做的,数据量大的时候都是1024分包发送,所以怎么调大数组缓存都只能接收到1024长度,
由于我做android端和服务器时候通讯我写是分包接收数据,所以尝试修改:
while (true)
{
oneTimeReciveString = OneTimeReceive();
Thread.Sleep(50);//线程等待,避免网络状况不好导致接收不完全
if (oneTimeReciveString.Length > 0)
{
reciveString = reciveString + oneTimeReciveString;
}
else
break;
}
return reciveString;
循环的逐个包接收,模拟器能把14899长度的文章接收完,分享一下,高手可以改进顺便通知我一下。
完整的类如下:
using System;
using System.Net.Sockets;
using System.Threading;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using System.Net;
namespace MSDNSocket
{
/// <summary>
/// 客户端通过TCP/IP连接服务端的方法,包含连接,发送数据,接收数据功能
/// </summary>
class SocketClient
{
// 定义一个空的Socket对象
Socket socket = null;
// 当一个异步操作完成时, 用于通知的事件对象
//创建一个手动线程通知事件,false表示默认是线程阻塞,true表示线程继续,只有线程继续WaitOne()才有意义
static ManualResetEvent clientDone = new ManualResetEvent(false);
// 异步操作超过时间定义. 如果在此时间内未接收到回应, 则放弃此操作.
const int TIMEOUT_MILLISECONDS = 5000;
// 用于接收数据的缓存数组大小
const int MAX_BUFFER_SIZE = 1024;
/// <summary>
/// 通过给定的地址和端口尝试TCP连接
/// </summary>
/// <param name="hostName">主机地址</param>
/// <param name="portNumber">通讯端口</param>
/// <returns>返回一个以字符串形式表示的连接结果</returns>
public string Connect(string hostName, int portNumber)
{
//连接结果,预定义为空
string result = string.Empty;
//通过给定的地址和端口创建一个网络终结点
DnsEndPoint hostEntry = new DnsEndPoint(hostName, portNumber);
// 给预定义的空的Socket对象赋值
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
// 创建一个SocketAsyncEventArgs 异步操作对象用于连接请求
SocketAsyncEventArgs socketEventArg = new SocketAsyncEventArgs();
//设置异步操作的DNS终结点
socketEventArg.RemoteEndPoint = hostEntry;
// Inline event handler for the Completed event.
// Note: This event handler was implemented inline in order to make this method self-contained.
socketEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(delegate(object s, SocketAsyncEventArgs e)
{
// 获取连接结果
result = e.SocketError.ToString();
//标识请求已经完成, 不阻塞 UI 线程
clientDone.Set();
});
// 重置clientDone,导致线程阻塞
clientDone.Reset();
// socket异步连接请求
socket.ConnectAsync(socketEventArg);
//阻塞UI线程,等待下一个线程,如超过指定时间则认为已经超时并开启UI线程
clientDone.WaitOne(TIMEOUT_MILLISECONDS);
//返回连接结果
return result;
}
/// <summary>
/// 发送指令数据至服务器
/// </summary>
/// <param name="data">要发送的指令</param>
/// <returns>发送结果,即成功或失败</returns>
public string Send(string data)
{
string response = "Operation Timeout";
// 使用在连接操作初始化的socket对象进行数据发送
if (socket != null)
{
// 创建 SocketAsyncEventArgs 对象、并设置对象属性
SocketAsyncEventArgs socketEventArg = new SocketAsyncEventArgs();
socketEventArg.RemoteEndPoint = socket.RemoteEndPoint;
socketEventArg.UserToken = null;
// 事件完成监听器
socketEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(delegate(object s, SocketAsyncEventArgs e)
{
response = e.SocketError.ToString();
//不阻塞UI线程
clientDone.Set();
});
// 将需要发送的数据指令送入发送缓冲区
byte[] payload = Encoding.Unicode.GetBytes(data);
socketEventArg.SetBuffer(payload, 0, payload.Length);
// 表示事件未完成,导致线程阻塞
clientDone.Reset();
// socket异步连接请求
socket.SendAsync(socketEventArg);
// 阻塞UI线程,等待下一个线程,如超过指定时间则认为已经超时并开启UI线程
clientDone.WaitOne(TIMEOUT_MILLISECONDS);
}
else
{
response = "Socket is not initialized";
}
return response;
}
public string Receive()
{
string reciveString = "";//服务端返回的整一串字符串,有可能包含有多个包
string oneTimeReciveString = "";//一次接收到的字符串,当有多个数据包的时候,每次只接收一个包
while (true)
{
oneTimeReciveString = OneTimeReceive();
Thread.Sleep(50);//线程等待,避免网络状况不好导致接收不完全
if (oneTimeReciveString.Length > 0)
{
reciveString = reciveString + oneTimeReciveString;
}
else
break;
}
return reciveString;
}
/// <summary>
/// 从服务端接收数据,此方法每次只接收一个数据包
/// </summary>
/// <returns>一个数据包</returns>
public string OneTimeReceive()
{
string response = "Operation Timeout";
if (socket != null)
{
// 创建 SocketAsyncEventArgs 对象、并设置对象属性
SocketAsyncEventArgs socketEventArg = new SocketAsyncEventArgs();
socketEventArg.RemoteEndPoint = socket.RemoteEndPoint;
// 设置接收数据缓冲区
socketEventArg.SetBuffer(new Byte[MAX_BUFFER_SIZE], 0, MAX_BUFFER_SIZE);
// Inline event handler for the Completed event.
// Note: This even handler was implemented inline in order to make
// this method self-contained.
socketEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(delegate(object s, SocketAsyncEventArgs e)
{
if (e.SocketError == SocketError.Success)
{
// 从接收缓冲区得到数据
response = Encoding.Unicode.GetString(e.Buffer, e.Offset, e.BytesTransferred);
//去除缓冲区多余的字节,即当返回数据的长度比缓冲字节数组小的时候,去除掉缓冲自己数组中有用数据外的字符
//数组中默认的字符为'\0'
response = response.Trim('\0');
}
else
{
response = e.SocketError.ToString();
}
clientDone.Set();
});
//表示事件未完成,导致线程阻塞
clientDone.Reset();
//socket异步连接请求
socket.ReceiveAsync(socketEventArg);
//阻塞UI线程,等待下一个线程,如超过指定时间则认为已经超时并开启UI线程
clientDone.WaitOne(TIMEOUT_MILLISECONDS);
}
else
{
response = "Socket is not initialized";
}
return response;
}
/// <summary>
/// 关闭socket并释放资源
/// </summary>
public void Close()
{
if (socket != null)
{
socket.Close();
}
}
}
}
相关文章
评论列表(0) 订阅
暂无评论
禁止评论