C# Socket异步通信

服务器端

TCPServer

1、使用的通讯通道:socket

2、用到的基本功能:

Bind,

Listen,

BeginAccept

EndAccept

BeginReceive

EndReceive

3、函数参数说明

Socketlistener=newSocket(AddressFamily.InterNetwork,
SocketType.Stream,ProtocolType.Tcp);

新建socket所使用的参数均为系统预定义的量,直接选取使用。

listener.Bind(localEndPoint);

localEndPoint 表示一个定义完整的终端,包括IP和端口信息。

//new IPEndPoint(IPAddress,port)

//IPAdress.Parse("192.168.1.3")

listener.Listen(100);

监听

listener.BeginAccept(
newAsyncCallback(AcceptCallback),
listener);

AsyncCallback(AcceptCallback),一旦连接上后的回调函数为AcceptCallback。当系统调用这个函数时,自动赋予的输入参数为IAsyncResoult类型变量ar。
listener,连接行为的容器。

Sockethandler=listener.EndAccept(ar);

完成连接,返回此时的socket通道。

handler.BeginReceive(state.buffer,0,StateObject.BufferSize,0,
newAsyncCallback(ReadCallback),state);

接收的字节,0,字节长度,0,接收时调用的回调函数,接收行为的容器。

========

容器的结构类型为:


publicclassStateObject
{
//Clientsocket.
publicSocketworkSocket=null;
//Sizeofreceivebuffer.
publicconstintBufferSize=1024;
//Receivebuffer.
publicbyte[]buffer=newbyte[BufferSize];
//Receiveddatastring.
publicStringBuildersb=newStringBuilder();
}

容器至少为一个socket类型。

===============

//Readdatafromtheclientsocket.
intbytesRead=handler.EndReceive(ar);

完成一次连接。数据存储在state.buffer里,bytesRead为读取的长度。

handler.BeginSend(byteData,0,byteData.Length,0,
newAsyncCallback(SendCallback),handler);

发送数据byteData,回调函数SendCallback。容器handler

intbytesSent=handler.EndSend(ar);

发送完毕,bytesSent发送字节数。

4 程序结构

主程序:



byte[]bytes=newByte[1024];

IPAddressipAddress
=IPAddress.Parse("192.168.1.104");
IPEndPointlocalEndPoint
=newIPEndPoint(ipAddress,11000);

//生成一个TCP的socket
Socketlistener=newSocket(AddressFamily.InterNetwork,
SocketType.Stream,ProtocolType.Tcp);

listener.Bind(localEndPoint);
listener.Listen(
100);

while(true)
{
//Settheeventtononsignaledstate.
allDone.Reset();

//开启异步监听socket
Console.WriteLine("Waitingforaconnection");
listener.BeginAccept(
newAsyncCallback(AcceptCallback),
listener);

//让程序等待,直到连接任务完成。在AcceptCallback里的适当位置放置allDone.Set()语句.
allDone.WaitOne();
}
Console.WriteLine(
"\nPressENTERtocontinue");
Console.Read();

连接行为回调函数AcceptCallback:


publicstaticvoidAcceptCallback(IAsyncResultar)
{
//添加此命令,让主线程继续.
allDone.Set();

//获取客户请求的socket
Socketlistener=(Socket)ar.AsyncState;
Sockethandler
=listener.EndAccept(ar);

//造一个容器,并用于接收命令.
StateObjectstate=newStateObject();
state.workSocket
=handler;
handler.BeginReceive(state.buffer,
0,StateObject.BufferSize,0,
newAsyncCallback(ReadCallback),state);
}

读取行为的回调函数ReadCallback:



publicstaticvoidReadCallback(IAsyncResultar)
{
Stringcontent
=String.Empty;

//从异步state对象中获取state和socket对象.
StateObjectstate=(StateObject)ar.AsyncState;
Sockethandler
=state.workSocket;

//从客户socket读取数据.
intbytesRead=handler.EndReceive(ar);

if(bytesRead>0)
{
//如果接收到数据,则存起来
state.sb.Append(Encoding.ASCII.GetString(state.buffer,0,bytesRead));

//检查是否有结束标记,如果没有则继续读取
content=state.sb.ToString();
if(content.IndexOf("<EOF>")>-1)
{
//所有数据读取完毕.
Console.WriteLine("Read{0}bytesfromsocket.\nData:{1}",
content.Length,content);
//给客户端响应.
Send(handler,content);
}
else
{
//接收未完成,继续接收.
handler.BeginReceive(state.buffer,0,StateObject.BufferSize,0,
newAsyncCallback(ReadCallback),state);
}
}
}

发送消息给客户端:


privatestaticvoidSend(Sockethandler,Stringdata)
{
//消息格式转换.
byte[]byteData=Encoding.ASCII.GetBytes(data);

//开始发送数据给远程目标.
handler.BeginSend(byteData,0,byteData.Length,0,
newAsyncCallback(SendCallback),handler);
}

privatestaticvoidSendCallback(IAsyncResultar)
{

//从state对象获取socket.
Sockethandler=(Socket)ar.AsyncState;

//完成数据发送
intbytesSent=handler.EndSend(ar);
Console.WriteLine(
"Sent{0}bytestoclient.",bytesSent);

handler.Shutdown(SocketShutdown.Both);
handler.Close();

}

在各种行为的回调函数中,所对应的socket都从输入参数的AsyncState属性获得。使用(Socket)或者(StateObject)进行强制转换。BeginReceive函数使用的容器为state,因为它需要存放传送的数据。

而其余接收或发送函数的容器为socket也可。

完整代码


usingSystem;
usingSystem.Net;
usingSystem.Net.Sockets;
usingSystem.Text;
usingSystem.Threading;

//Stateobjectforreadingclientdataasynchronously
publicclassStateObject
{
//Clientsocket.
publicSocketworkSocket=null;
//Sizeofreceivebuffer.
publicconstintBufferSize=1024;
//Receivebuffer.
publicbyte[]buffer=newbyte[BufferSize];
//Receiveddatastring.
publicStringBuildersb=newStringBuilder();
}


publicclassAsynchronousSocketListener
{
//Threadsignal.
publicstaticManualResetEventallDone=newManualResetEvent(false);

publicAsynchronousSocketListener()
{
}


publicstaticvoidStartListening()
{
//Databufferforincomingdata.
byte[]bytes=newByte[1024];

//Establishthelocalendpointforthesocket.
//TheDNSnameofthecomputer
//runningthelisteneris"host.contoso.com".
//IPHostEntryipHostInfo=Dns.Resolve(Dns.GetHostName());
IPAddressipAddress=IPAddress.Parse("192.168.1.104");
IPEndPointlocalEndPoint
=newIPEndPoint(ipAddress,11000);

//CreateaTCP/IPsocket.
Socketlistener=newSocket(AddressFamily.InterNetwork,
SocketType.Stream,ProtocolType.Tcp);

//Bindthesockettothelocalendpointandlistenforincomingconnections.
try
{
listener.Bind(localEndPoint);
listener.Listen(
100);

while(true)
{
//Settheeventtononsignaledstate.
allDone.Reset();

//Startanasynchronoussockettolistenforconnections.
Console.WriteLine("Waitingforaconnection");
listener.BeginAccept(
newAsyncCallback(AcceptCallback),
listener);

//Waituntilaconnectionismadebeforecontinuing.
allDone.WaitOne();
}


}

catch(Exceptione)
{
Console.WriteLine(e.ToString());
}


Console.WriteLine(
"\nPressENTERtocontinue");
Console.Read();

}


publicstaticvoidAcceptCallback(IAsyncResultar)
{
//Signalthemainthreadtocontinue.
allDone.Set();

//Getthesocketthathandlestheclientrequest.
Socketlistener=(Socket)ar.AsyncState;
Sockethandler
=listener.EndAccept(ar);

//Createthestateobject.
StateObjectstate=newStateObject();
state.workSocket
=handler;
handler.BeginReceive(state.buffer,
0,StateObject.BufferSize,0,
newAsyncCallback(ReadCallback),state);
}


publicstaticvoidReadCallback(IAsyncResultar)
{
Stringcontent
=String.Empty;

//Retrievethestateobjectandthehandlersocket
//fromtheasynchronousstateobject.
StateObjectstate=(StateObject)ar.AsyncState;
Sockethandler
=state.workSocket;

//Readdatafromtheclientsocket.
intbytesRead=handler.EndReceive(ar);

if(bytesRead>0)
{
//Theremightbemoredata,sostorethedatareceivedsofar.
state.sb.Append(Encoding.ASCII.GetString(
state.buffer,
0,bytesRead));

//Checkforend-of-filetag.Ifitisnotthere,read
//moredata.
content=state.sb.ToString();
if(content.IndexOf("<EOF>")>-1)
{
//Allthedatahasbeenreadfromthe
//client.Displayitontheconsole.
Console.WriteLine("Read{0}bytesfromsocket.\nData:{1}",
content.Length,content);
//Echothedatabacktotheclient.
Send(handler,content);
}

else
{
//Notalldatareceived.Getmore.
handler.BeginReceive(state.buffer,0,StateObject.BufferSize,0,
newAsyncCallback(ReadCallback),state);
}

}

}


privatestaticvoidSend(Sockethandler,Stringdata)
{
//ConvertthestringdatatobytedatausingASCIIencoding.
byte[]byteData=Encoding.ASCII.GetBytes(data);

//Beginsendingthedatatotheremotedevice.
handler.BeginSend(byteData,0,byteData.Length,0,
newAsyncCallback(SendCallback),handler);
}


privatestaticvoidSendCallback(IAsyncResultar)
{
try
{
//Retrievethesocketfromthestateobject.
Sockethandler=(Socket)ar.AsyncState;

//Completesendingthedatatotheremotedevice.
intbytesSent=handler.EndSend(ar);
Console.WriteLine(
"Sent{0}bytestoclient.",bytesSent);

handler.Shutdown(SocketShutdown.Both);
handler.Close();

}

catch(Exceptione)
{
Console.WriteLine(e.ToString());
}

}



publicstaticintMain(String[]args)
{
StartListening();
return0;
}

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值