由于项目需要, 我需要通过 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. 最漂亮的Spring事务管理详解

    SnailClimb 2018年05月21日阅读 7245 可能是最漂亮的Spring事务管理详解 Java面试通关手册(Java学习指南):github.com/Snailclimb/- 微信阅读地 ...

  2. 如何让后加载的元素被一开始就有的css样式渲染成功(强制提升css优先级)

    今天在做搜索框中的提示语下拉的时候,提示框把搜索框的底部的border遮住,导致看起来不是很美观: 因为下方的提示框是用js后加载的它的样式也是随着js一起加载的,而这个js和它的css我们是不能改动 ...

  3. 微信js sdk分享开发摘记java版

    绑定域名和引入js的就不说了 废话不说直接上代码 public void share(HttpServletRequest request) throws Exception { StringBuff ...

  4. 通过WMI获取网卡MAC地址、硬盘序列号、主板序列号、CPU ID、BIOS序列号

    转载:https://www.cnblogs.com/tlduck/p/5132738.html #define _WIN32_DCOM #include<iostream> #inclu ...

  5. ubuntu 18 python3.6更换国内源和pip3源

    1.更换国内源 查看Ubuntu18版本和codename(一定要注意codename对应) lsb_release -a No LSB modules are available. Distribu ...

  6. html 中js 如何给字符串加换行符

    var str = 你好'+"\n"+ '世界'; 这种写法在html中是会被识别为"你好\n世界" 那么如何保证其这么写会被识别,只需要在该div的样式中加入 ...

  7. js中数组的循环与遍历forEach,map

    对于前端的循环遍历我们知道有 针对js数组的forEach().map().filter().reduce()方法 针对js对象的for/in语句(for/in也能遍历数组,但不推荐) 针对jq数组/ ...

  8. CN109241772A发票区块链记录方法、装置、区块链网关服务器和介质(腾讯)

    学习笔记-2 CN109241772A发票区块链记录方法.装置.区块链网关服务器和介质(腾讯) 解决什么问题? 让发票信息记录到区块链的情况下减少发票信息泄露 链上有什么数据? 发行发票事件信息(发票 ...

  9. 单播反向路径转发uRPF

    uRPF将数据包的源地址和存储在转发信息库(FIB)中的信息进行对照,以判定数据包的合法性.FIB是Cisco CEF技术中的一张表,包含从路由表中复制过来的转发信息,可以将其视为路由表的镜像,FIB ...

  10. IO课堂测试

    一,用户需求 英语的26 个字母的频率在一本小说中是如何分布的?某类型文章中常出现的单词是什么?某作家最常用的词汇是什么?<哈利波特与魔法石> 中最常用的短语是什么,等等. (1)要求1: ...