android/java 与 c#进行socket通信

4 篇文章 0 订阅
1 篇文章 0 订阅

开发环境:

客户端:java  myEclipse8.5

服务端:c# vs2008

 

此例子内java 代码来自 http://blog.csdn.net/xd1210aaa/article/details/7074459 

java 与 c#是两种完全不同实现机制的语言,但是可以通过socket作为桥梁,做相应的沟通,本例为大家展示,如何编写java c#之间进行通信。

此技术点本没有什么难度可言,但在笔者实践的过程中发现java 与c#的utf-8编码格式的显示方式上有一定区别。所以造成中文乱码。花了2个小时左右写了一种算法,虽然不怎么灵巧,而且可能会影响程序性能,但是可以解决乱码问题,特在此注明,若为追求程序性能,tcpip包内只用发单字节就可以了,这样简单的发送可以处理两种语言通讯时产生的事件,从而实现java端调用c#端相应的方法,或相反,若要实现聊天类似的功能(包括中文),则需要使用此算法。

 

以下java代码,改动send方法

public String send(String msg)
	{
		try {
			
			System.out.println("发送的内容:" + msg);
			
			PrintWriter out = new PrintWriter(socket.getOutputStream());	
			byte[] b = msg.getBytes("UTF-8");
			
			StringBuffer buffer = new StringBuffer();
			for (int i = 0; i < b.length; i++) {
				buffer.append(b[i]+256).append(",");
			}
			
			out.print(buffer.toString());
			out.flush();
			
			return null;
			
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}

 

 

大家是否注意到,b[i] + 256 ,

这是因为在java中,byte型是有符号的,取值范围在-128 到127,而c#的byte型则是0-255,无符号型,在此需要对byte进行转换,转为c#可识别的byte编码,b[i]+256则可以实现效果。付下图,c# 与 java 不同的utf-8表示形式,汉字“呵呵”;

 

 

 

以下为c#端代码

 

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

namespace AndroidAndCSharp
{
    public partial class Form1 : Form
    {
        
        //监听对象
        Socket listener;

        private const int PORT = 9758; //监听端口
        private static IPAddress IP;           //本地网卡地址

        public Form1()
        {
            InitializeComponent();
            
            //获取本地网卡地址
            IP = Form1.GetIP();
            //实例化监听对象
            listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //启动线程
            backgroundWorker1.RunWorkerAsync();
        }

        /// <summary>
        /// 获取本地网卡地址
        /// </summary>
        /// <returns></returns>
        public static System.Net.IPAddress GetIP()
        {
            System.Net.IPAddress ip = System.Net.IPAddress.Parse("127.0.0.1");

            System.Net.IPHostEntry host = System.Net.Dns.GetHostEntry(System.Net.Dns.GetHostName());

            foreach (System.Net.IPAddress item in host.AddressList)
            {
                if (item.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
                {
                    return item;
                }
            }
            //如果没有找到可用地址,则用回环地址
            return ip;
        }


        /// <summary>
        /// 多线程控件 , 当线程开始时
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            EndPoint ip = new IPEndPoint(Form1.IP, Form1.PORT);

            //监听绑定好的ip与端口
            listener.Bind(ip);
            //设置缓冲区大小,单位为字节
            listener.ReceiveBufferSize = 100;
            //挂起连接的最大长度
            listener.Listen(10);

            while(true)
            {
                //开始监听,并等待数据
                Socket socket = listener.Accept();

                byte[] buffer = new byte[100];

                socket.Receive(buffer);

                //线程向外部发送报告
                backgroundWorker1.ReportProgress(1 , buffer);

                socket.Close();
            }
        }

        /// <summary>
        /// 多线程控件,当线程向外发出报告时
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            //从线程内部获取附加参数
            byte[] b = (byte[])e.UserState;

            byte[] buffer = new byte[b.Length];
            string[] str = new string[b.Length];

            for (int i = 0,j = 0; i < b.Length; i++)
            {
                //去掉缓冲区内未使用的空间
                if (b[i] != 0)
                {
                    //不为逗号
                    if (b[i] != 44)
                    {
                        str[j] += (char)b[i];
                    }
                    else
                    {
                        j++;
                    }
                }
                else
                {
                    break;
                }
            }

            for (int i = 0; i < str.Length; i++)
            {
                //不对缓冲区内垃圾区域做处理
                if (str[i] != null)
                {
                    buffer[i] = Convert.ToByte(str[i]);
                }
                else
                {
                    break;
                }
            }

            //把转换后的c#可识别编码字节数组转为字符串
            string msg = Encoding.UTF8.GetString(buffer);

            textBox1.Text = msg;
        }


    }
}


 

在backgroundWorker1_ProgressChanged方法中,对java 端发来的字符进行处理,转为c#可识别并有效的转为string的算法。

请注意,c#在设置监听时,需要获取本地网卡地址。

 

程序运行结果

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值