实现Winform与Sliverlight之间的Socket通信转换

众所周知,Winform下的Socket与Sliverlight的Socket是不可以直接通信的,原因请参考http://www.cnblogs.com/ZetaChow/archive/2009/05/16/2237347.html。以下是经本人验证过的转换方法,具体流程为:先建立一个winform
client端接收已存在的winform server端发来的信息,将接收到的信息通过新建的sliverlight server端发出,再建立一个sliverlight client端接收此消息,如此一来便也达到了用sliverlight接收winform消息的效果。代码如下:

1.建立winform client

#region 接收来自源Server的客户端

Dictionary<string, ConnClientHelp> dictConn = new Dictionary<string, ConnClientHelp>();

Socket socketClient = null;

Thread threadClient = null;

public void Client()

{

try

{

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

IPAddress ipaddress = GetIP("192.168.0.3");

IPEndPoint endpoint = new IPEndPoint(ipaddress, 8889);

socketClient.Connect(endpoint);

threadClient = new Thread(RecMsg);

threadClient.IsBackground = true;

threadClient.Start();

}

catch (Exception ex)

{ }

}

/// <summary>

/// 接收服务端发来信息的方法

/// </summary>

private void RecMsg()

{

while (true) //持续监听服务端发来的消息

{

try

{

byte[] arrRecMsg = new byte[1024 * 1024 * 10];

length = socketClient.Receive(arrRecMsg);

strRecMsg = Encoding.UTF8.GetString(arrRecMsg, 0, length);

foreach (ConnClientHelp conn in dictConn.Values)

{

conn.Send(strRecMsg, conn);

}

}

catch (Exception eee)

{ }

}

}

#endregion

2.建立sliverlight server

#region 向Sliverlight发送的服务端

Thread threadServer = null; //负责监听客户端的线程

Socket socketServer = null; //负责监听客户端的套接字

Socket socConnection;//创建一个负责和客户端通信的套接字

public void Server()

{

try

{

//定义一个套接字用于监听客户端发来的信息  包含3个参数(IP4寻址协议,流式连接,TCP协议)

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

//服务端发送信息 需要1个IP地址和端口号

IPAddress ipaddress = IPAddress.Parse("192.168.2.103");

//将IP地址和端口号绑定到网络节点endpoint上

IPEndPoint endpoint = new IPEndPoint(ipaddress, 4530);

//监听绑定的网络节点

socketServer.Bind(endpoint);

//将套接字的监听队列长度限制为40

socketServer.Listen(40);

//创建一个监听线程

threadServer = new Thread(WatchConnecting);

//将窗体线程设置为与后台同步

threadServer.IsBackground = true;

//启动线程

threadServer.Start();

}

catch (Exception mmm)

{ }

}

/// <summary>

/// 监听客户端发来的请求

/// </summary>

private void WatchConnecting()

{

while (true)  //持续不断监听客户端发来的请求

{

try

{

socConnection = socketServer.Accept();

//创建一个通信线程

ParameterizedThreadStart pts = new ParameterizedThreadStart(ServerRecMsg);

Thread thr = new Thread(pts);

thr.IsBackground = true;

//启动线程

thr.Start(socConnection);

ConnClientHelp connection = new ConnClientHelp(socConnection);

//将负责与当前连接请求客户端 通信的套接字所在的连接通信类 对象 装入集合

dictConn.Add(socConnection.RemoteEndPoint.ToString(), connection);

}

catch (Exception ex)

{ }

}

}

/// <summary>

/// 发送信息到客户端的方法

/// </summary>

/// <param name="sendMsg">发送的字符串信息</param>

private void ServerSendMsg(string sendMsg)

{

//将输入的字符串转换成 机器可以识别的字节数组

byte[] arrSendMsg = Encoding.UTF8.GetBytes(sendMsg);

//向客户端发送字节数组信息

socConnection.Send(arrSendMsg);

}

/// <summary>

/// 接收客户端发来的信息

/// </summary>

/// <param name="socketClientPara">客户端套接字对象</param>

private void ServerRecMsg(object socketClientPara)

{

try

{

Socket socketServer = socketClientPara as Socket;

if (true)

{

//创建一个内存缓冲区 其大小为1024*1024字节  即1M

byte[] arrServerRecMsg = new byte[1024 * 1024];

//将接收到的信息存入到内存缓冲区,并返回其字节数组的长度

int length = socketServer.Receive(arrServerRecMsg);

//将机器接受到的字节数组转换为人可以读懂的字符串

string strSRecMsg = Encoding.UTF8.GetString(arrServerRecMsg, 0, length);

}

}

catch (Exception ee)

{ }

}

#endregion

3.建立sliverlight client

#region 客户端,将接收到的数据发送至地图

private Socket socket;

private void ConnectSocket()

{

DnsEndPoint hostEntry = new DnsEndPoint("192.168.2.103", 4530);//建立终结点对象

socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//创建一个Socket对象

SocketAsyncEventArgs socketEventArg = new SocketAsyncEventArgs();//创建Socket异步事件参数

byte[] buffer = Encoding.UTF8.GetBytes("Start");//将消息转化为发送的byte[]格式

socketEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(socketArgs_Completed);//注册Socket完成事件

socketEventArg.RemoteEndPoint = hostEntry;//设置Socket异步事件远程终结点

socketEventArg.UserToken = buffer;//将定义好的Socket对象赋值给Socket异步事件参数的运行实例属性

try

{

socket.ConnectAsync(socketEventArg);

}

catch (SocketException ex)

{

throw new SocketException((int)ex.ErrorCode);

}

}

private void socketArgs_Completed(object sender, SocketAsyncEventArgs e)

{

//检查是否发送出错

if (e.SocketError != SocketError.Success)

{

if (e.SocketError == SocketError.ConnectionAborted){Dispatcher.BeginInvoke(() => MessageBox.Show("连接超时....请重试!"));}

else if (e.SocketError == SocketError.ConnectionRefused){Dispatcher.BeginInvoke(() => MessageBox.Show("无法连接到服务器端:" + e.SocketError));}

else {Dispatcher.BeginInvoke(() => MessageBox.Show(e.SocketError.ToString())); }

return;

}

if (e.LastOperation == SocketAsyncOperation.Connect)

{

//客户端步骤二:连接服务器成功,将需要发送的数据放入缓冲区中,然后异步向服务器发送消息请求

byte[] userbytes = (byte[])e.UserToken;

e.SetBuffer(userbytes, 0, userbytes.Length);

socket.SendAsync(e);

}

else if (e.LastOperation == SocketAsyncOperation.Send)

{

//客户端步骤三:消息发送成功,此时设置一个新的缓冲区实例,并且发起异步接收服务器返回的消息

byte[] userbytes = new byte[1024 * 1024];

e.SetBuffer(userbytes, 0, userbytes.Length);

socket.ReceiveAsync(e);

}

else if (e.LastOperation == SocketAsyncOperation.Receive)

{

byte[] userbytes = new byte[1024 * 1024];

//客户端步骤四:获取到服务器返回的消息

string RecevieStr = Encoding.UTF8.GetString(e.Buffer, 0, e.Buffer.Length).Replace("\0", "");

Dispatcher.BeginInvoke(() => { MessageBox.Show(RecevieStr); });

}

#endregion

4.用到的三个help文件

(1)clientaccesspolicy.xml

<?xml version="1.0" encoding="UTF-8"?>

-<access-policy>

-<cross-domain-access>

-<policy>

-<allow-from>

<domain uri="*"/>

</allow-from>

-<grant-to>

<socket-resource protocol="tcp" port="4502-4534"/>

</grant-to>

</policy>

</cross-domain-access>

</access-policy>

(2)program.cs

using System;

using System.Collections.Generic;

using System.Linq;

using System.Windows.Forms;

using System.IO;

using System.Net.Sockets;

using System.Net;

using System.Threading;

namespace TransClientServer

{

static class Program

{

static void Main(string[] args)

{

//策略步骤一:启动监听943端口是否有需要安全策略文件请求

Thread access = new Thread(new ThreadStart(accessThread));

access.Start();

Application.EnableVisualStyles();

Application.SetCompatibleTextRenderingDefault(false);

Application.Run(new transForm());

}

//策略请求监听

static void accessThread()

{

//获取943端口监听的Socket服务端

Socket socket = GetSocketServer(943);

while (true)

{

Socket new_access = socket.Accept();

string clientPolicyString = "<policy-file-request/>";

byte[] requestbytes = new byte[clientPolicyString.Length];

new_access.Receive(requestbytes);

string requeststring = System.Text.Encoding.UTF8.GetString(requestbytes, 0, requestbytes.Length);

if (requeststring == clientPolicyString)

{

//策略步骤二:如果客户端请求是<policy-file-request/>,则将安全策略文件作为bytes发送给客户端

byte[] accessbytes = GetPolicyToClient();

new_access.Send(accessbytes, accessbytes.Length, SocketFlags.None);

new_access.Close();

}

Thread.Sleep(100);

}

}

//根据端口建立Socket服务器端

static Socket GetSocketServer(int serverPort)

{

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

socket.Bind(new IPEndPoint(IPAddress.Any, serverPort));

socket.Listen(40);

return socket;

}

//获取安全策略文件的byte[]

static byte[] GetPolicyToClient()

{

string path = Environment.CurrentDirectory.Replace("\\bin\\Debug", "");

FileStream fs = new FileStream(path + @"\clientaccesspolicy.xml", FileMode.Open);

int length = (int)fs.Length;

byte[] bytes = new byte[length];

fs.Read(bytes, 0, length);

fs.Close();

return bytes;

}

}

}

(3)ConnClientHelp.cs

using System;

using System.Collections.Generic;

using System.Threading;

using System.Net;

using System.Net.Sockets;

using System.Text;

using System.IO;

using System.Windows.Forms;

namespace TransClientServer.Help

{

/// <summary>

/// 与客户端的 连接通信类(包含了一个 与客户端 通信的 套接字,和线程)

/// </summary>

class ConnClientHelp

{

Socket sokMsg;

Thread threadMsg;

#region 构造函数

/// <summary>

///

/// </summary>

/// <param name="sokMsg">通信套接字</param>

public ConnClientHelp(Socket sokMsg)

{

this.sokMsg = sokMsg;

this.threadMsg = new Thread(RecMsg);

this.threadMsg.IsBackground = true;

this.threadMsg.Start();

}

#endregion

bool isRec = true;

#region 02负责监听客户端发送来的消息

void RecMsg()

{

while (isRec)

{

try

{

byte[] arrMsg = new byte[1024 * 1024 * 10];

//接收 对应 客户端发来的消息

int length = sokMsg.Receive(arrMsg);

//将接收到的消息数组里真实消息转成字符串

string strMsg = System.Text.Encoding.UTF8.GetString(arrMsg, 0, length);

}

catch (Exception ex)

{

}

}

}

#endregion

#region 03向客户端发送消息

/// <summary>

/// 向客户端发送消息

/// </summary>

/// <param name="strMsg"></param>

public void Send(string strMsg, ConnClientHelp conn)

{

try

{

byte[] arrMsg = System.Text.Encoding.UTF8.GetBytes(strMsg);

byte[] arrMsgFinal = new byte[arrMsg.Length + 1];

arrMsgFinal[0] = 0;//设置 数据标识位等于0,代表 发送的是 文字

arrMsg.CopyTo(arrMsgFinal, 1);

sokMsg.Send(arrMsgFinal);

}

catch (Exception ex)

{

if ("远程主机强迫关闭了一个现有的连接。".Equals(ex.Message))

{

conn.CloseConnection();

}

}

}

#endregion

#region 04关闭与客户端连接

/// <summary>

/// 关闭与客户端连接

/// </summary>

public void CloseConnection()

{

threadMsg.Interrupt();

isRec = false;

}

#endregion

}

}

转载/引用请注明出处,谢谢!

时间: 2024-10-09 19:12:20

实现Winform与Sliverlight之间的Socket通信转换的相关文章

Java与C之间的socket通信

最近正在开发一个基于指纹的音乐检索应用,算法部分已经完成,所以尝试做一个Android App.Android与服务器通信通常采用HTTP通信方式和Socket通信方式.由于对web服务器编程了解较少,而且后台服务器已经采用原始socket实现与c客户端通信,这就要求Android客户端也采用socket实现.所以在开发Android app时采用了原始socket进行编程. 由于算法是用C语言实现的,而Android应用一般是Java开发,这就不可避免得涉及Java和C语言之间的通信问题.一种

WinForm版聊天室复习Socket通信

聊天室:服务器端-------------客户端 最终演示展示图: 一. 服务器端 对服务端为了让主窗体后台不处理具体业务逻辑,因此对服务端进行了封装,专门用来处理某个客户端通信的过程. 而由于通信管理类中需要处理具体与某个客户端的通信业务,所以在构造函数中传入了具体的套接字对象. 针对消息提醒:由于需要再通信管理类中进行消息提示,而需要调用主窗体的ShowMsg方法.因此将打印消息的方法通过委托传给了通信管理类的构造函数 同理针对意外关闭的客户端连接也同样通过委托将移除客户端的方法传给了通信管

服务器之间借助Socket通信

正在完成一个并行仿真优化系统,系统流程大致上是如此的:用户在网页端提交需要进行R&S的系统候选集(以及各种参数设置)给主实体服务器,主实体服务器借助Tornado框架处理请求报文,然后借助Socket将系统候选集提交给虚拟机集群的主节点(集群一共16台Linux虚拟机),虚拟机集群在计算的同时,用户还会不断和主实体服务器交互,因此主实体服务器需要随时从主节点获取系统状态,反馈给用户. 关于socket,尽管很早上操作系统.计算机网络等等课程的时候就知道了,但一直没有真正的机会运用,现在先来了解一

【转】Winform Socket通信

Socket相关概念[端口] 在Internet上有很多这样的主机,这些主机一般运行了多个服务软件,同时提供几种服务.每种服务都打开一个Socket,并绑定到一个端口上,不同的端口对应于不同的服务(应用程序). 例如:http 使用80端口  ftp使用21端口 smtp 25端口 有两种类型:50000 ?  流式Socket(STREAM): 是一种面向连接的Socket,针对于面向连接的TCP服务应用,安全,但是效率低: ?  数据报式Socket(DATAGRAM): 是一种无连接的So

Winform Socket通信

原文地址:http://www.cnblogs.com/DrHao/p/4953532.html Socket相关概念[端口] 在Internet上有很多这样的主机,这些主机一般运行了多个服务软件,同时提供几种服务.每种服务都打开一个Socket,并绑定到一个端口上,不同的端口对应于不同的服务(应用程序). 例如:http 使用80端口  ftp使用21端口 smtp 25端口 有两种类型:50000 ?  流式Socket(STREAM): 是一种面向连接的Socket,针对于面向连接的TCP

.net平台下C#socket通信(中)

本文主要讲述: 1.正常通信中握手建立 2.一对多的通信 3.发送接收数据格式转换 4.资源释放 5.开启并保持服务监听 1.握手建立正常的通信通道 项目需要通信的双方(假设是一个上位机.一个下位机)之间需要建立一个稳定的通道,以便进行通信.本项目中具体操作是:上位机作为服务器,下位机作为客户端,同时制定通信协议.上位机首先打开监听等待建立通道,下位机主动连接上位机后发送连接成功的信息到上位机,上位机根据通信协议发送数据到下位机,此时通道已经建立.但为了保险起见(同时遵循三次握手),客户端再次发

.net平台下C#socket通信(转)

上篇.net平台下C#socket通信(上)介绍了socket通信的基本原理及最基本的通信方式.本文在此基础上就socket通信时经常遇到的问题做一个简单总结,都是项目中的一些小问题,拿来此处便于下次使用,同时对在使用socket时出现些许问题的同仁们多一个粗浅建议.不足之处请提出,谢谢. 本文主要讲述: 1.正常通信中握手建立 2.一对多的通信 3.发送接收数据格式转换 4.资源释放 5.开启并保持服务监听 1.握手建立正常的通信通道 项目需要通信的双方(假设是一个上位机.一个下位机)之间需要

TCP及socket通信原理

一.网络互联模型 因特网在刚面世时,只有同一制造商生产的计算机才能彼此通信,制定网络互联模型的目的就是为异种的计算机互连提供一个共同的基础和标准框架,并为保持相关标准的一致性和兼容性提供共同的参考. 互联参考模型: OSI七层模型(Open System Interconnect):应用层.表示层.会话层.传输层.网络层.数据链路层.物理层 DoD四层模型:是OSI七层模型的浓缩版,包括 进程/应用层.主机到主机层.因特网层.网络接入层 以上两种模型是层次型的,分层模型的优点主要在于: ①将网络

php的socket通信

对TCP/IP.UDP.Socket编程这些词你不会很陌生吧?随着网络技术的发展,这些词充斥着我们的耳朵.那么我想问: 1.         什么是TCP/IP.UDP?2.         Socket在哪里呢?3.         Socket是什么呢?4.         你会使用它们吗? 什么是TCP/IP.UDP? TCP/IP(Transmission Control Protocol/Internet Protocol)即传输控制协议/网间协议,是一个工业标准的协议集,它是为广域网