由于项目需要, 我需要通过 Java 开发的服务端对 C# 作为脚本语言开发的 unity 项目实现控制

话不多说, 直接上代码

首先, 我们先来构建服务端的代码, 服务端我们使用 Java 语言

import org.slf4j.Logger;
import org.slf4j.LoggerFactory; /*
*@Description //TODO Socket 服务端$
*@Author 吾王剑锋所指 吾等心之所向
*@Date 2019/8/20 14:42
*/
public class SocketServer {
private static Logger LOGGER = LoggerFactory.getLogger(SocketServer.class); private static SocketServer instance = null;
private boolean flag = true;public void start(){
new Thread(new SocketThread(), "socket server").start();
while (!flag) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
LOGGER.error(e.getMessage(), e);
}
}
}
}

上面这段代码作为一个开关, 负责启动 socket 服务

接着, 我们来写一个线程,  负责在服务启动后监听 port 端口发来的连接请求

import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import java.net.ServerSocket;
import java.net.Socket; /*
*@Description //TODO socket 通信线程$
*@Author 吾王剑锋所指 吾等心之所向
*@Date 2019/8/19 14:49
*/
public class SocketThread implements Runnable {
private static Logger LOGGER = LoggerFactory.getLogger(SocketThread.class); private static final Integer port = 5656; @Override
public void run() {
ServerSocket serverSocket = null;
try{
serverSocket = new ServerSocket(port);
LOGGER.info("socket server start, monitor 5656 port ! ");
Socket socket = serverSocket.accept();
new SocketClientRequest(socket).start();
LOGGER.info("send success ! ");
}catch (Exception ex){
LOGGER.error("send fail ! ");
} try {
Thread.sleep(5000);
} catch (InterruptedException e) {
LOGGER.error("Server delayed restart failed ! ");
}
}
}

接着, 再写一个线程, 负责在监听到连接后, 接收客户端发来的信息和向客户端发送信息

import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket; /*
*@Description //TODO socket 客户端请求线程$
*@Author 吾王剑锋所指 吾等心之所向
*@Date 2019/8/20 14:54
*/
public class SocketClientRequest extends Thread{
private static Logger LOGGER = LoggerFactory.getLogger(SocketClientRequest.class); private int messageLengthBytes = 1024;
public Socket socket;
private BufferedInputStream bufferedInputStream = null; public SocketClientRequest(Socket socket) {
this.socket = socket;
} @Override
public void run() {
try {
//获取socket中的数据
bufferedInputStream = new BufferedInputStream(socket.getInputStream());
byte[] clientCharStream = new byte[messageLengthBytes]; bufferedInputStream.read(clientCharStream);
System.out.println(new String(clientCharStream, "utf-8")); OutputStream(socket); //发送信息到客户端
} catch (IOException e) {
LOGGER.error("read massage error [{}]", e);
}
} /**
* 向客户端发送指定信息
* */
private static void OutputStream(Socket socket) throws IOException {
OutputStream out = socket.getOutputStream();
out.write(new String("welcome_send_server!").getBytes());
}
}

到这里,  socket 的服务端代码就搞定了, 接着, 我们来写客户端的代码

客户端我使用 unity 作为客户端程序, 所以用C#作为客户端的编程语言

因为知识做一个实验, 所以随随便便新建一个项目就行了

在文件夹处新建一个 script 文件夹, 用于保存程序文件, 然后在建两个C#文件, 双击打开

using System;
using System.Collections;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using UnityEngine; public class SocketUtils{ private static SocketUtils socketUtils = new SocketUtils(); private Socket socket; //单例模式
public static SocketUtils GetInstance()
{
return socketUtils;
} private SocketUtils()
{ //采用TCP方式连接
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //服务器IP地址
IPAddress address = IPAddress.Parse("127.0.0.1"); //服务器端口
IPEndPoint endpoint = new IPEndPoint(address, ); //异步连接,连接成功调用connectCallback方法
IAsyncResult result = socket.BeginConnect(endpoint, new AsyncCallback(ConnectCallback), socket); //这里做一个超时的监测,当连接超过5秒还没成功表示超时
bool success = result.AsyncWaitHandle.WaitOne(, true);
if (!success)
{
//超时
Closed();
Debug.Log("connect Time Out");
}
else
{
//与socket建立连接成功,开启线程接受服务端数据。
Thread thread = new Thread(new ThreadStart(ReceiveSorket));
thread.IsBackground = true;
thread.Start();
} } private void ConnectCallback(IAsyncResult asyncConnect)
{
Debug.Log("connect success");
} private void ReceiveSorket()
{
//在这个线程中接受服务器返回的数据
while (true)
{ if (!socket.Connected)
{
//与服务器断开连接跳出循环
Debug.Log("Failed to clientSocket server.");
socket.Close();
break;
}
try
{
//接受数据保存至bytes当中
byte[] bytes = new byte[];
int i = socket.Receive(bytes);
if (i <= )
{
socket.Close();
break;
}
Debug.Log(System.Text.Encoding.Default.GetString(bytes));
}
catch (Exception e)
{
Debug.Log("Failed to clientSocket error." + e);
socket.Close();
break;
}
}
} //关闭Socket
public void Closed()
{
if (socket != null && socket.Connected)
{
socket.Shutdown(SocketShutdown.Both);
socket.Close();
}
socket = null;
}
//向服务端发送一条字符
public void SendMessage(string str)
{
byte[] msg = Encoding.UTF8.GetBytes(str); if (!socket.Connected)
{
socket.Close();
return;
}
try
{
IAsyncResult asyncSend = socket.BeginSend(msg, , msg.Length, SocketFlags.None, new AsyncCallback(SendCallback), socket);
bool success = asyncSend.AsyncWaitHandle.WaitOne(, true);
if (!success)
{
socket.Close();
Debug.Log("Failed to SendMessage server.");
}
}
catch
{
Debug.Log("send message error");
}
} private void SendCallback(IAsyncResult asyncConnect)
{
Debug.Log("send success");
}
}

然后是

using System.Collections;
using System.Collections.Generic;
using UnityEngine; public class SocketMain : MonoBehaviour {
void Start () {
//创建socket连接
SocketUtils s = SocketUtils.GetInstance();
//发送信息向服务器端
s.SendMessage("啦啦啦");
}
}

再将 SocketMain.cs 挂载到相机上

这样子, 服务端和客户端就简单的实现了 socket 连接

先启动服务端

socket 服务端启动成功,  接着启动客户端

客户端已经成功收到服务端发来的信息

服务端也接受到了客户端的信息

这样子, 一个简单的双工通讯就新建成功了

但是这样的系统还有很多问题没有解决,

例如: service 层要怎么调用 socket 实现主动控制服务端向客户端发送信息呢?

于是我决定使用netty来做一次升级, 因为netty的框架还提供了很多别的功能, 使得整个通讯系统变得更加的健壮,

详情跳转我的另一篇博文 https://www.cnblogs.com/unityworld/p/11425180.html

[经验] Java 服务端 和 C# 客户端 实现 Socket 通信的更多相关文章

  1. 成功使Linux服务端和Windows客户端建立socket通信

    一.准备工作 1.一台装有虚拟机的Windows7操作系统,虚拟机中装的是CentOS6.5版本的Linux 2.Windows7已经装有java环境 二.编码 使用java编写socket通信的服务 ...

  2. Delphi服务端和PHP客户端通过Socket通信

    在开始之前看下效果 PHP页面作为客户端发送请求给作为服务端的Delphi应用程序 PHP客户端页面打开如下 Delphi服务端应用程序打开如下 每次PHP页面刷新一下,Delphi的文本框都显示&q ...

  3. “快的打车”创始人陈伟星的新项目招人啦,高薪急招Java服务端/Android/Ios 客户端研发工程师/ mysql DBA/ app市场推广专家,欢迎大家加入我们的团队! - V2EX

    "快的打车"创始人陈伟星的新项目招人啦,高薪急招Java服务端/Android/Ios 客户端研发工程师/ mysql DBA/ app市场推广专家,欢迎大家加入我们的团队! - ...

  4. Rest Post示例(java服务端、python客户端)

    前提:服务端是现成的,java.springMVC.resttemplate.jboss等:突然有个需要,要在windows上开发一个客户端,作用是定期向服务端上传文件.想了想,如果客户端写一个jav ...

  5. jsonp协议 java服务端、JQuery客户端 简单实现原理

    原文链接:https://blog.csdn.net/Activity_Time/article/details/96440806 1. 概述 Jsonp(JSON with Padding) 是 j ...

  6. Socket通讯-C#客户端与Java服务端通讯(发送消息和文件)

    设计思路 使用websocket通信,客户端采用C#开发界面,服务端使用Java开发,最终实现Java服务端向C#客户端发送消息和文件,C#客户端实现语音广播的功能. Java服务端设计 packag ...

  7. Flex通信-Java服务端通信实例

    转自:http://blessht.iteye.com/blog/1132934Flex与Java通信的方式有很多种,比较常用的有以下方式: WebService:一种跨语言的在线服务,只要用特定语言 ...

  8. RPC学习--C#使用Thrift简介,C#客户端和Java服务端相互交互

    本文主要介绍两部分内容: C#中使用Thrift简介 用Java创建一个服务端,用C#创建一个客户端通过thrift与其交互. 用纯C#实现Client和Server C#服务端,Java客户端 其中 ...

  9. C#使用Thrift简介,C#客户端和Java服务端相互交互

    C#使用Thrift简介,C#客户端和Java服务端相互交互 本文主要介绍两部分内容: C#中使用Thrift简介 用Java创建一个服务端,用C#创建一个客户端通过thrift与其交互. 用纯C#实 ...

随机推荐

  1. php中的elseif和else if

    以前的时候还没注意到,知道进入公司,看的代码多了点,时常看到elseif的分支,而我自己时常用的是else if,于是就注意到,他们既然都可以用,那么他们的却别在哪儿呢? 通过查询,原来,确实有点小小 ...

  2. 对DensePose: Dense Human Pose Estimation In The Wild的理解

    研究方法 通过完全卷积学习从图像像素到密集模板网格的映射.将此任务作为一个回归问题,并利用手动注释的面部标注来训练我们的网络.使用这样的标注,在三维对象模板和输入图像之间,建立密集的对应领域,然后作为 ...

  3. SPOJ Distinct Substrings

    给定一个字符串,求不相同子串个数.每个子串一定是某个后缀的前缀,那么原问题等价于求所有后缀之间的不相同子串个数.总数为n*(n-1)/2,再减掉height[i]的和就是答案 #include< ...

  4. TD tree体验

    在体验了学长们设计的app后,我颇有感触,我们也可以凭借自己的力量来开发一款软件,虽然它可能并不如市面上相同类型的那么完美,但它对我们的意义却是不一样的. 我是在下午的见面会上看到的这款软件,接待的学 ...

  5. MyBatis 传一个类型为String的参数时常见问题及解决方法

    MyBatis要求如果参数为String的话,不管接口方法的形参是什么,在Mapper.xml中引用时需要改变为_parameter才能识别 : <select id="selectB ...

  6. GridView 列表组件 以及动态 GridView

        1.通过 GridView.builder 实现网格布局 Widget getList(context, index) { return Container( margin: EdgeInse ...

  7. 05-Docker-Container资源限制

    目录 05-Docker-Container资源限制 参考 可压缩性 MEM限制 选项说明 压测示例 CPU限制 选项说明 压测示例 05-Docker-Container资源限制 Docker Ve ...

  8. VScode Vim插件快速上手与配置

    快速安装: 打开market place,搜索vim即可安装. 基本改建与配置说明: 方向键: 用I k j l表示光标上下左右,需要编辑visual mode和normal mode { " ...

  9. powerbuilder连接oracle数据库

    一.打开已经安装好的pb9.0,主界面菜单栏有个两个圆柱形就行数据库连接,点击database. 二.选择oracle版本,由于数据库版本是9i,可以使用084 oracle8/8i.右键--选择ne ...

  10. Centos7 虚拟环境安装Django 出现ImproperlyConfigured('SQLite 3.8.3 or later is required (found %s).' %Database.sqlite_version)错误

    Centos7 虚拟环境安装Django 出现SQLite版本问题 raise ImproperlyConfigured('SQLite 3.8.3 or later is required (fou ...