欢迎光临
我们一直在努力

Silverlight使用JavaSocket连接jabber服务器

Vs2010Sl4jdk6MyEclipse8.5

 

1、Silverlight socket 数据交换端口必须在4502-4534范围 

2、必须创建一个Socket监听943端口(该端口是固定的,客户端策略请求固定发送到该端口) 

 

 

 

1、去官网下载 smack jar包  http://www.igniterealtime.org/downloads/source.jsp

2、引入jar包,如下:

3、编写socket 的服务器端

import java.io.BufferedReader;

import java.io.IOException;

import java.io.InputStreamReader;

import java.io.PrintWriter;

import java.net.ServerSocket;

import java.net.Socket;

import java.util.ArrayList;

import java.util.List;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

import org.jivesoftware.smack.ConnectionConfiguration;

import org.jivesoftware.smack.XMPPConnection;

 

/**

 * @author geolo

 * 

 * @使用须知

 *    1. 每一个Socket客服端连接成功后会驻留在后台,因此在Jabber退出时一定要关闭自己的Socket,为保持客户端正常连接,所以不能采用垃圾收集器 <br />

 *    2. 连接Jabber的格式是 "userName,password".比如-->geolo,364200<-- 注意用“逗号”做分隔符 <br />

 *    3. 关闭Socket的格式是"Socket_Exit," 比如-->Socket_Exit,<--注意用“逗号”做尾符 <br />

 *    4. 如果Jabber登录成功会收到“LOGIN_TURE”提示 <br />

 *    5. 如果Jabber登录失败会收到“LOGIN_FALSE”提示   <br />

 *    6. 服务器Socket只有在重启的时候才会被关闭,否则一直保持等待客服端Socket登录状态。  <br />

 *    7. 服务器的IP视本机地址而定。端口号位4502.  <br />

 *    8. 感谢使用.

 */

public class Server{

//服务器端口

private static final int SERVERPORT = 4502; 

//客户端连接

private static List<Socket> mClientList = new ArrayList<Socket>(); 

//线程池

private ExecutorService mExecutorService;  

//ServerSocket对象

private ServerSocket mServerSocket;  

//Jabber连接对象

XMPPConnection xmppConnection;

 

//开启服务器

public static void main(String[] args){

new Server();

 

public Server(){

try{

//设置服务器端口

mServerSocket = new ServerSocket(SERVERPORT);

//创建一个线程池

mExecutorService = Executors.newCachedThreadPool();

system.out.println("start...");

try {

 

//用来临时保存客户端连接的Socket对象

Socket client = null;

while (true){

//接收客户连接并添加到list

client = mServerSocket.accept(); 

mClientList.add(client);

 

//设置Jabber端口  

xmppConnection = new XMPPConnection(new ConnectionConfiguration("wyu.0101.com.cn", 5222));

xmppConnection.connect();//连接Jabber

System.out.println("连接成功");

 

//开启一个客户端线程

mExecutorService.execute(new ThreadServer(xmppConnection,client));

} catch (Exception e) {

System.out.println("连接失败");   e.printStackTrace();

catch (IOException e){

System.out.println("登录失败3");

e.printStackTrace();

}   

 

//每个客户端单独开启一个线程

static class ThreadServer implements Runnable{

private SocketmSocket;

private BufferedReadermBufferedReader;

private PrintWritermPrintWriter;

private StringmStrMSG;

XMPPConnection connection;

String isLogined;//登录是否成功

 

public ThreadServer(XMPPConnection xmppConnection,Socket socket) throws IOException{

if(this.mSocket != socket && this.connection != xmppConnection){

this.mSocket = socket;

this.connection = xmppConnection;

 

mBufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));

sendMessage(mSocket,"Socket: "+this.mSocket.getInetAddress());

 

public void run(){

try{

isLogined = "LOGIN_FALSE";

if(mStrMSG.indexOf(",") < 0){

sendMessage(mSocket,isLogined);

}else{

String strArray[] = mStrMSG.split(",");

if (strArray[0].trim().equalsIgnoreCase("Socket_Exit")){

sendMessage(mSocket,"Socket closed");

//当一个客户端退出时

mClientList.remove(mSocket);

mBufferedReader.close();

mPrintWriter.close();

mSocket.close();

connection.disconnect();

break;

}else{

try {

System.out.println("name: "+strArray[0]+" password: "+strArray[1]);

connection.login(strArray[0], strArray[1]);

isLogined = "LOGIN_TURE";

} catch (Exception e) {

isLogined = "LOGIN_FALSE";

System.out.println("错误2");

sendMessage(mSocket,isLogined);

}catch (Exception e){

System.out.println("错误3");

 

//发送消息给所对应的客户端

private void sendMessage(Socket client,String message) throws IOException{

mPrintWriter = new PrintWriter(client.getOutputStream(), true);

mPrintWriter.println(message);

 

4、运行 java Appcation

1、界面设计如下:

2、界面代码

<UserControl x:Class="SlToJavaSocket.MainPage"

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

    mc:Ignorable="d"

    d:DesignHeight="300" d:DesignWidth="400">

    <Grid  Name ="LayoutRoot"  Background ="White"  ShowGridLines ="True">

        <Grid.RowDefinitions >

            <RowDefinition />

            <RowDefinition />

        </Grid.RowDefinitions >

        <TextBox x:Name="txtToSend" Grid.Row ="0"/>

        <Button Grid.Row ="1" Click ="OnSend" Content ="Send" Margin ="20" />

    </Grid >

</UserControl>

 

3、后台代码

using System;

using System.Collections.Generic;

using System.Linq;

using System.Net;

using System.Windows;

using System.Windows.Controls;

using System.Windows.Documents;

using System.Windows.Input;

using System.Windows.Media;

using System.Windows.Media.Animation;

using System.Windows.Shapes;

using System.Net.Sockets;

using System.Threading;

using System.Text;

 

namespace SlToJavaSocket

    public partial class MainPage : UserControl

    {

        public MainPage()

        {

            InitializeComponent();

        }

 

        // 定义一个可在全局使用的Socket

 

        System.Net.Sockets.Socket socket;

 

 

 

        // 定义一个同步上下文类,用来将子线程的操作调度到主线程上以可控制UI 属性。

 

 

 

 

        // 发送信息按钮的单击事件

 

        void OnSend(object sender, RoutedEventArgs args)

        {

 

 

            // 定义一个字节数组,并将文本框的的类容转换为字节数组后存入

 

            byte[] bytes = Encoding.UTF8.GetBytes(txtToSend.Text);

 

 

 

            // 显示信息,可不要。

 

            txtToSend.Text += "\r\nDnsSafeHost:" + Application.Current.Host.Source.DnsSafeHost;

 

 

 

            // 将同步上下文设置在当前上下文(线程,主线程,可控制UI 的)

 

            syn = SynchronizationContext.Current;

 

 

 

            // 为socket 创建示例,并设置相关属性。

 

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

 

 

 

            // 定义并实例一个Socket 参数

 

            SocketAsyncEventArgs socketArgs = new SocketAsyncEventArgs();

 

 

            socketArgs.SocketClientAccessPolicyProtocol = SocketClientAccessPolicyProtocol.Tcp;

            // 设置到远程终节点属性(4502 端口,为什么是4502 ,MS 的SL 通信安全上有)

 

            //socketArgs.RemoteEndPoint = new DnsEndPoint(Application.Current.Host.Source.DnsSafeHost, 4510);

            socketArgs.RemoteEndPoint = new DnsEndPoint(Application.Current.Host.Source.DnsSafeHost, 4502);

 

 

            // 设置好当Socket 任何一个动作完成时的回调函数。

 

            socketArgs.Completed += new EventHandler<SocketAsyncEventArgs>(socketArgs_Completed);

 

            //Socket 参数的用户标识,实际上就是一个可以传递的OBJECT 参数。

 

            socketArgs.UserToken = bytes;

 

            // 执行连接。

 

           MessageBox.Show( (socket.ConnectAsync(socketArgs)).ToString());

 

 

        }

 

 

 

        void socketArgs_Completed(object sender, SocketAsyncEventArgs e)

        {

 

            // 当任何一个Socket 动作完成,都回调该函数,然后对LastOperation 进行判断后继续执行相应的部分

 

            switch (e.LastOperation)

            {

 

                case SocketAsyncOperation.Connect:

 

                    ProcessConnect(e);

 

                    break;

 

                case SocketAsyncOperation.Receive:

 

                    ProcessReceive(e);

 

                    break;

 

                case SocketAsyncOperation.Send:

 

                    ProcessSend(e);

 

                    break;

 

            }

 

        }

 

 

 

 

        void ProcessConnect(SocketAsyncEventArgs e)

        {

 

 

 

            // 当连接成功后,获取Socket 参数 e 传递过来的用户标识(也就是本示例中用户输入的字符串转换的Byte 字节数组)

 

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

 

 

 

            // 设置Socket 参数的缓冲区参数,将我们的字节数组设置为Socket 的缓冲区。

 

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

 

 

 

            // 同步一下上下文,显示一下当前的状态信息。

 

            syn.Post(GetText, "States:" + e.SocketError.ToString() + "," + e.LastOperation.ToString());

 

 

 

            // 发送数据

 

            socket.SendAsync(e);

 

 

 

        }

 

 

 

        // 发送完成后,执行等待接收服务器发回的数据

 

        void ProcessSend(SocketAsyncEventArgs e)

        {

 

            // 定义个空的字节数组,设置好其大小

 

            byte[] bytes = new byte[1024];

 

            // 将前面定义字节数组设置成缓冲区

 

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

 

            // 执行异步接收

 

            socket.ReceiveAsync(e);

 

        }

 

 

 

        // 当接收完成后

 

        void ProcessReceive(SocketAsyncEventArgs e)

        {

 

            // 在执行好接收后,本地SOCKET 的缓冲区就会被服务器发送的数据填充。

 

            // 显示下信息,当然也是用同步上下文的方式,在显示信息的时候,就直接将缓冲区的字节数组转换成字符串。

 

            syn.Post(GetText, Encoding.UTF8.GetString(e.Buffer, 0, e.Buffer.Length) + " and Received");

 

            // 关闭Socket 连接

 

            socket.Close();

 

            // 最后显示下,Socket 关闭。

 

            syn.Post(GetText, "Socket Closed");

 

        }

 

 

 

        // 同步上下文调用的方法。

 

        void GetText(object str)

        {

 

            txtToSend.Text += "\r\n" + str.ToString();

 

        }

 

 

    }

 

 

1Silverlight端运行效果:

2、java端运行效果

3、恭喜,连上 服务器(lxflxf 是指我在服务器上注册的用户名和密码)

 

 

1、把 策略文件放到  服务器 943 端口 (类似于开个socket , 发送 策略文件)

2、Silverlight 对外端口 4502-4534 (设置超过或小于后果自负)

3、如果是win7 系统的一定要注意 IIS中 用户的权限(我就在这悲剧了半天~

 

 

  • 海报
海报图正在生成中...
赞(0) 打赏
声明:
1、本博客不从事任何主机及服务器租赁业务,不参与任何交易,也绝非中介。博客内容仅记录博主个人感兴趣的服务器测评结果及一些服务器相关的优惠活动,信息均摘自网络或来自服务商主动提供;所以对本博客提及的内容不作直接、间接、法定、约定的保证,博客内容也不具备任何参考价值及引导作用,访问者需自行甄别。
2、访问本博客请务必遵守有关互联网的相关法律、规定与规则;不能利用本博客所提及的内容从事任何违法、违规操作;否则造成的一切后果由访问者自行承担。
3、未成年人及不能独立承担法律责任的个人及群体请勿访问本博客。
4、一旦您访问本博客,即表示您已经知晓并接受了以上声明通告。
文章名称:《Silverlight使用JavaSocket连接jabber服务器》
文章链接:https://www.456zj.com/597.html
本站资源仅供个人学习交流,请于下载后24小时内删除,不允许用于商业用途,否则法律问题自行承担。

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址