用async与await 写socket客户端!!!

taz01 2015-06-24 06:16:25
刚刚接触socket 看了软件官方 的demo 太多代码,就想用重新写一次
参考了好多资料,最终代码如下:
运行一次是正确有,但运行多次的时候 就会出错。
求大神指点一下



class Program
{
static void Main(string[] args)
{
var cmd = "add 1 2 4" + Environment.NewLine;
Task.Run(async delegate { await SocketExts.SendAsync(cmd); });
Task.Run(async delegate { await SocketExts.SendAsync(cmd); });
Task.Run(async delegate { await SocketExts.SendAsync("ECHO this is a test"
+ Environment.NewLine); });
Task.WaitAll(Task.Delay(2000));
}
}

public static class SocketExts
{
public async static Task<string> SendAsync(string msg,
string ip = "127.0.0.1", int port = 2012)
{
using (var client = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp))
{
var remoteEP = new IPEndPoint(IPAddress.Parse(ip), port);
await Task.Factory.FromAsync(client.BeginConnect,
client.EndConnect, remoteEP, null);

byte[] byteData = Encoding.ASCII.GetBytes(msg);
var result = client.BeginSend(byteData, 0, byteData.Length, 0,
_ => { }, client);
await Task.Factory.FromAsync(result, (r) => client.EndSend(r));

StateObject state = new StateObject();
state.workSocket = client;
var received = client.BeginReceive(state.buffer, 0,
StateObject.BufferSize, 0,
_ => { }, state);
var response = await Task<string>.Factory.FromAsync(received, ar =>
{
ReceiveCallback(ar);
return ((StateObject)ar.AsyncState).sb.ToString();
});


Console.WriteLine("=======Response received : {0}=====", response);
client.Shutdown(SocketShutdown.Both);
client.Close();
return response;
}
}
private static void ReceiveCallback(IAsyncResult ar)
{
StateObject state = (StateObject)ar.AsyncState;
Socket client = state.workSocket;
int bytesRead = client.EndReceive(ar);
if (bytesRead > 0)
{
state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead));
client.BeginReceive(state.buffer, 0, bytesRead, SocketFlags.None,
new AsyncCallback(ReceiveCallback), client);
}
}
}

public class StateObject
{
public Socket workSocket = null;
public const int BufferSize = 1024;
public byte[] buffer = new byte[BufferSize];
public StringBuilder sb = new StringBuilder();
}
...全文
458 1 打赏 收藏 转发到动态 举报
写回复
用AI写文章
1 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
在.net中,尽量不要使用Socket。它不是基于IOCP的,它是用来一些人移植java代码用的。应该使用TcpListner和TcpClient,这样才能在并发量大时获得性能提升。 你的代码有太多的需要修改的地方了,实在是难以一一指出(太累了)。最为重要的一点,比如说tcp是会自动平衡网络带宽的,因此有着粘包和分包的结果,而你的代码 state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead)); 则完全不考虑分包的情况。 我曾经贴过一个 Tcp 长连接的“底层”的例子(没有包括信令的业务处理部分):http://bbs.csdn.net/topics/390987992 虽然在信令上比你的这个短链接的稍微复杂(2、3条语句),但是还是可以参考一下。里边对于许多必须考虑到的底层的东西都基本上有所演示。

110,531

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧