//第一篇:http://bbs.eeworld.com.cn/thread-117409-1-1.html

server(PC):

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

using System.Net;
using System.Net.Sockets;
using System.Threading;

namespace WinSocketServer
{
public partial class FmServer : Form
{
Thread mythread;
Socket socket;

public FmServer()
{
InitializeComponent();
}

public static IPAddress GetServerIP()
{
IPHostEntry ieh = Dns.GetHostByName(Dns.GetHostName());
return ieh.AddressList[0];
}

private void BeginListen()
{
IPAddress ServerIp = GetServerIP();//是不是把这里的地址,换成外网的就可以了?我在局域网里可以实现 IPEndPoint iep = new IPEndPoint(ServerIp, 8000);

socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

byte[] byteMessage = new byte[100];
this.label1.Text = "正在侦听:" + iep.ToString();

try
{
socket.Bind(iep);
}
catch (System.Exception ex)
{
MessageBox.Show(ex.Message);
}

while (true)
{
try
{
socket.Listen(5);

Socket newSocket = socket.Accept();
newSocket.Receive(byteMessage);

this.label1.Text = "连接已成功。";

string[] str = newSocket.RemoteEndPoint.ToString().Split(':');

this.listBox1.Items.Add("At:" + DateTime.Now.ToShortTimeString() + " From:" + str[0]);
this.listBox1.Items.Add(Encoding.Default.GetString(byteMessage));
}
catch (SocketException ex)
{
string a = ex.Message;
this.label1.Text = ex.ToString();
}
}
}

private void btnLisent_Click(object sender, System.EventArgs e)
{
if (this.btnLisent.Text == "侦听")
{
try
{
mythread = new Thread(new ThreadStart(BeginListen));
mythread.Start();

this.btnLisent.Text = "停止";
}
catch (System.Exception er)
{
MessageBox.Show(er.Message, "完成", MessageBoxButtons.OK, MessageBoxIcon.Stop);
}
}
else
{
socket.Close();
mythread.Abort();

this.btnLisent.Text = "侦听";
this.label1.Text = "连接已关闭。";
}
}
}
}

client(wince模拟器):

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

using System.Net;
using System.Threading;
using System.Net.Sockets;
using System.IO;

namespace DevScoketClient
{
public partial class FmClient : Form
{
Socket socket;
IPEndPoint iep;

public FmClient()
{
InitializeComponent();
}

private void btnConnect_Click(object sender, EventArgs e)
{
string ip = this.tbIP.Text;
string port = this.tbPort.Text;

try
{
IPAddress serverIp = IPAddress.Parse(ip);
int serverPort = Convert.ToInt32(port);

iep = new IPEndPoint(serverIp, serverPort);

socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket.Connect(iep);
socket.Send(Encoding.ASCII.GetBytes(tbInfo.Text.Trim()));
socket.Shutdown(SocketShutdown.Both);
socket.Close();

labStatus.Text = "Send succeed !";
}
catch (System.Exception ex)
{
string a = ex.Message;
labStatus.Text = "Connection failed !";
}
}
}
}

//第二篇:http://blog.csdn.net/ivy_napoloan/article/details/7175283

由 于在应用时:PC端的主要工作是连接PDA端,并向PDA端发送如打开(Open)条形码扫描模块 ,扫描(Scan)条形码等指令,并接受PDA的操作结果;而PDA端则是根据PC端发送过来的指令然后执行相应的操作,并将结果发回给PC端,如打开 (Open)成功则返回 “打开成功!”,扫描条形码成功则将扫描结果发送给PC。因此PDA需要作为服务端(Server ),而PC端需要作为客户端(Client)。

而在选择连接方式时发现:在基于ActiveSync 的Socket通信时PDA端只能作为客户端(Client具体实现参考:点击打开链接),不符合要求,所以选择通过Wlan连接PC与PDA。

首先是PC端(Client):

PC端的工作很简单,只需要发送指令,并接收指令处理结果就可以了。

1.定义接口:IMsgReceiverSender

[csharp] view plaincopy
  1. public interface IMsgReceiverSender  
  2.    {  
  3.        bool Connect(string ip, int port);// 连接手持机  
  4.        bool SendMsg(Request msg);// 发送消息  
  5.        void DisConnect();// 断开连接  
  6.        void StartListening();// 开始监听线程  
  7.        void StopListening();// 停止监听线程  
  8.    }  

1.1.Connect  连接手持机:在连接成功后立即开启监听线程,准备接收PDA发送过来的数据。

[csharp] view plaincopy
  1. this.tcpClient = new TcpClient();  
  2. this.tcpClient.Connect(IPAddress.Parse(ip), port); // 连接手持机  
  3.   
  4. this.networkStream = tcpClient.GetStream(); // 获取连接至远程的流  
  5. this.OnClientConnected(EventArgs.Empty);    // 触发连接成功事件  
  6.   
  7. this.StartListening();// 开始监听从手持机发送过来的消息  

1.2.SendMsg 发送指令:连接成功后就可以向PDA发送指令了。

[csharp] view plaincopy
  1. lock (this.networkStream)  
  2. {  
  3. <span>    </span>if (this.networkStream.CanWrite)                              
  4.      ProtocolHandler.Write(this.networkStream, request);//  向手持机发送指令  
  5. }  

1.3.DisConnect  断开连接:当不需要在PC与PDA之间传输数据时断开连接

[csharp] view plaincopy
  1. if (this.networkStream != null)  
  2.     this.networkStream.Close();  
  3.   
  4. if (this.tcpClient != null)  
  5.     this.tcpClient.Close();  

1.4.StartListening 启动监听线程 :在连接建立TCP连接成功后开始监听PDA发送数据的端口。

[csharp] view plaincopy
  1. this.workerThread = new Thread(new ThreadStart(ListenThreadMethod));  
  2. this.workerThread.IsBackground = true;  
  3. this.workerThread.Start();  

1.4.1.ListenThreadMethod  监听PDA发送过来的数据线程入口方法

[csharp] view plaincopy
  1. while (true)  
  2. {  
  3.     try  
  4.     {// 读取手持机发送过来的消息  
  5.         Reponse reponse = ProtocolHandler.Read(this.networkStream);  
  6.   
  7.         if (reponse != null)// 触发接收到信息事件     
  8.             this.OnMessageReceived(new MsgReceiveEvnentArgs(reponse));                 
  9.     }  
  10.     catch (Exception)  
  11.     {  
  12.         this.OnConnectionLost(EventArgs.Empty);// 触发连接断开事件  
  13.         break;// 退出循环  
  14.     }  
  15. }  

1.5.StopListening 停止监听线程:在端口连接时调用

[csharp] view plaincopy
  1. if (this.tcpListener != null)  
  2. {  
  3.     this.tcpListener.Stop();// 停止监听  
  4.     this.tcpListener = null;  
  5. }  
  6. if (this.workerThread != null)  
  7. {  
  8.     this.workerThread.Abort();  
  9.     Thread.Sleep(100);  // 等待线程结束  
  10. }  

客户端(Client)基本上就完成了,当然在实际应用时还需要添加如:连接超时,订立协议等内容,这将在之后提及。

PDA端(Server 
PDA端作为服务端与PC端基本一致,只是在 StartListening(开启监听线程)时需要在指定的本地 IP 地址和端口号上侦听是否有传入的连接尝试。
1.定义借口 :IMsgReceiverSender
[csharp] view plaincopy
  1. public interface IMsgReceiverSender  
  2.    {  
  3.        bool DisConnect();// 注销连接  
  4.        bool SendMsg(Reponse reponse);// 发送响应数据  
  5.        void StartListening();// 开始监听线程  
  6.        void StopListening();// 停止监听线程  
  7.    }  
1.1. Disconnect 注销连接:在不需要使用TCP连接的时候调用
[csharp] view plaincopy
  1. if (this.networkStream != null)  
  2.     this.networkStream.Close();  
  3.   
  4.  if (this.client != null)  
  5.      this.client.Close();  
1.2. SendMsg 发送响应数据:将处理完PC端发送过来的指令后的结果返回给PC

[csharp] view plaincopy
  1. lock (this.networkStream)  
  2. {  
  3.     if(this.networkStream.CanWrite)  
  4.     // 向PC端发送响应信息  
  5.     ProtocolHandler.Write(networkStream, reponse);  
  6. }  
1.3.StopListening 停止监听:在注销连接时调用
[csharp] view plaincopy
  1. <span style="white-space:pre">        </span>if (this.listenser != null)  
  2.                {  
  3.                    this.listenser.Stop();//停止监听  
  4.                    this.listenser = null;  
  5.                }  
  6.   
  7.                if (this.workThread != null)  
  8.                {  
  9.                    this.workThread.Abort();  
  10.                    Thread.Sleep(100); // 等待背景线程结束  
  11.                }  
1.4.StartListening 开始监听:在程序启动时就调用
[csharp] view plaincopy
  1. this.workThread = new Thread(new ThreadStart(this.ListenThreadMethod));  
  2. this.workThread.IsBackground = true;  
  3. this.workThread.Start();  

1.4.1.ListenThreadMethod 监听线程


[csharp] view plaincopy
  1. <span style="white-space:pre">    </span>    IPHostEntry ipHostEntry = Dns.GetHostEntry(Dns.GetHostName());  
  2.            IPAddress[] ips = ipHostEntry.AddressList;  
  3.            IPAddress localIP = null;  
  4.            localIP = ips[0];// 本机IP地址  
  5.            this.listenser = new TcpListener(localIP, localPort);  
  6.            this.listenser.Start();  
  7.   
  8.            while (true)  
  9.            {  
  10.                try  
  11.                {  
  12.                    client = this.listenser.AcceptTcpClient();  
  13.                }  
  14.                catch  
  15.                {  
  16.                    break;  
  17.                }  
  18.                // 触发连接成功事件  
  19.                this.OnClientConnected(EventArgs.Empty);  
  20.   
  21.                this.networkStream = this.client.GetStream();  
  22.   
  23.                while (true)  
  24.                {  
  25.                    try  
  26.                    {  
  27.                        Request cmd = Protocol.ProtocolHandler.Read(this.networkStream);  
  28.   
  29.                        if (cmd != null)  
  30.                        {  
  31.                            // 触发接收到消息事件  
  32.                            this.OnMessageReceived(new MsgEventArgs(cmd));  
  33.                        }  
  34.                    }  
  35.                    catch (Exception)  
  36.                    {  
  37.                        // 触发断开连接事件  
  38.                        this.OnClientLost(EventArgs.Empty);  
  39.                        break;  
  40.                    }  
  41.                }  
  42.            }  

以 上基本能满足传输数据的要求了,但是仅仅这样是不够的,在项目中PC端发送的指令,PDA端发送的响应信息都很不规范,所以需要我们自己把这些数据做进一 步的处理再进行传输。通常都是使用XML进行传输,所以在我订立的协议里面也是使用XML序列化和反序列化所传输的对象,让程序处理更简便。