飞夺泸定桥

我心飞扬

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

以用socket通讯发送和接受坐标点对(x,y)为例:

  C#异步socket通讯--服务器端

  在异步socket服务端中,建立连接、接收数据、发送数据都要设置回调函数。在每次监听连接、接收和发送数据是都需要调用BeginXXX的过程。特别需要注意的是,在接收数据时,若要不停的监听数据,每次收到数据后要立刻调用BeginReceive函数(见代码中的ReadCallback函数);每次接收的实际数据可能小于设置的缓冲区大小(数据包小于缓冲区长度时)。

View Code
public class Channel
{
// Thread signal.
public static ManualResetEvent allDone = new ManualResetEvent(false);
static Channel instance = null;
private bool isConnected;
private byte[] buf;
float x, y;
Socket socket, listener;
public static Channel Instance()
{
if (instance == null)
{
instance
= new Channel();
}
return instance;
}
private Channel()
{

buf
= new byte[1024];
isConnected
= false;
x
= 0;
y
= 0;
}

public bool startServer(string strIP,int portNum)
{
socket
= new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//初始化socket
listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//初始化socket
IPAddress[] ipAddr = Dns.GetHostAddresses(strIP);
IPAddress ip
= ipAddr[0];
IPEndPoint hostEP
= new IPEndPoint(ip, portNum);
try
{
listener.Bind(hostEP);
listener.Listen(
100);
// Set the event to nonsignaled state.
allDone.Reset();
listener.BeginAccept(
new AsyncCallback(AcceptCallback),listener);
// Wait until a connection is made before continuing.
allDone.WaitOne();

}
catch (System.Exception ex)
{
MessageBox.Show(ex.ToString());
return false;
}
return true;
}
public void AcceptCallback(IAsyncResult ar)
{
// Signal the main thread to continue.
allDone.Set();
// Get the socket that handles the client request.
listener = (Socket)ar.AsyncState;
socket
= listener.EndAccept(ar);
//读取客户端内容
Thread t = new Thread(new ThreadStart(threadrecv));
t.Start();
socket.BeginReceive(buf,
0, 1024, 0,new AsyncCallback(ReadCallback),null);
isConnected
= true;
}
private void threadrecv()
{
socket.BeginReceive(buf,
0, 1024, 0, new AsyncCallback(ReadCallback), socket);
}
public void ReadCallback(IAsyncResult ar)
{
int byteread = socket.EndReceive(ar);
x
= BitConverter.ToSingle(buf, 12);
y
= BitConverter.ToSingle(buf, 16);
socket.BeginReceive(buf,
0, 1024, 0, new AsyncCallback(ReadCallback), socket);
}
private void SendCallback(IAsyncResult ar)
{
try
{
// Retrieve the socket from the state object.
Socket handler = (Socket)ar.AsyncState;
// Complete sending the data to the remote device.
int bytesSent = handler.EndSend(ar);
}
catch (Exception e)
{
MessageBox.Show(e.ToString());
}
}

public bool getPoint(ref float x,ref float y)
{
x
= this.x;
y
=this.y;
return true;
}

public bool close()
{
try
{
socket.Shutdown(SocketShutdown.Both);
socket.Close();
listener.Close();
}
catch (System.Exception ex)
{
MessageBox.Show(ex.Message);
return false;
}

return true;
}
public bool sendPoint(float x, float y)
{
if(isConnected==false)
{
return false;
}
float flag = 0;
byte[] bf = BitConverter.GetBytes(flag);
byte[] bx = BitConverter.GetBytes(x);
byte[] by = BitConverter.GetBytes(y);
byte[] buffer = new byte[50];
bf.CopyTo(buffer,
0);
bx.CopyTo(buffer,
4);
by.CopyTo(buffer,
8);
bf.CopyTo(buffer,
12);
bf.CopyTo(buffer,
16);
socket.BeginSend(buffer,
0,20,0,new AsyncCallback(SendCallback), socket);
return true;
}
}

  

  C#同步socket通讯

     同步通讯比较简单,见代码(服务器端与客户端代码差别不大)

View Code
public class Channel
{
static Channel instance = null;
private bool isConnected;
private byte[] buf;
private NetworkStream ns;
Socket socket;
public static Channel Instance()
{
if (instance == null)
{
instance
= new Channel();
}
return instance;
}
private Channel()
{
socket
= new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//初始化socket
buf = new byte[1024];
isConnected
= false;
}
public bool connect(string strIP,int portNum,int readTimeOut)
{

IPAddress [] ipAddr
=Dns.GetHostAddresses(strIP);
IPAddress ip
=ipAddr[0];
IPEndPoint hostEP
=new IPEndPoint(ip,portNum);
isConnected
= true;
try
{

Socket s
= new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//初始化socket
s.Bind(hostEP);
s.Listen(
0);
socket
= s.Accept();
//尝试连接 客户端时
//socket=socket.Connect(hostEP);
}
catch(Exception se)
{
MessageBox.Show(
"连接错误"+se.Message,"提示信息",
MessageBoxButtons.RetryCancel,MessageBoxIcon.Information);
isConnected
= false;
return false;
}
ns
= new NetworkStream(socket);
if (readTimeOut < 0)
readTimeOut
= 0;
ns.ReadTimeout
= readTimeOut;
return isConnected;
}

public bool getPoint(ref float x,ref float y)
{
if(isConnected==false)
{
return false;
}
try
{
if (ns.DataAvailable)
{
while (ns.DataAvailable)
{
ns.Read(buf,
0, 20);
}
}
else
{
ns.Read(buf,
0, 20);
}
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
return false;
}
x
=BitConverter.ToSingle(buf, 12);
y
= BitConverter.ToSingle(buf, 16);
return true;
}

public bool close()
{
try
{
if (ns != null)
{
ns.Close();
}
if (socket != null)
{
socket.Close();
}
}
catch (System.Exception ex)
{
MessageBox.Show(ex.Message);
return false;
}

return true;
}
public bool sendPoint(float x, float y)
{
if(isConnected==false)
{
return false;
}
float flag = 0;
byte[] bf = BitConverter.GetBytes(flag);
byte[] bx = BitConverter.GetBytes(x);
byte[] by = BitConverter.GetBytes(y);
bf.CopyTo(buf,
0);
bx.CopyTo(buf,
4);
by.CopyTo(buf,
8);
bf.CopyTo(buf,
12);
bf.CopyTo(buf,
16);
try
{
ns.Write(buf,
0, 20);
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
return false;
}
ns.Flush();
return true;
}
}

   总结:在实时性要求比较高的系统中,用异步通讯是较好的选择;同步通讯由于发送和接收都是阻塞调用的,当需要接收数据而端口没有数据过来的时候,需要等待较长的时间影响系统性能,用多线程的方法对数据进行接收和发送也许是一个不错的选择,有待试验(例如在连接建立的同时开一个线程处理接收数据的函数)。

posted on 2011-03-04 21:54  飞夺泸定桥  阅读(5771)  评论(0编辑  收藏  举报