Unity 3 D入門2:Socket初探査
ここ数日Socketインタラクションを検討した. ネット上の資料でSocketに関する最初のDemoを作りましたが、あまり成熟していませんが、個人的には比較的完全な感じがします.各タイプのデータの転送受付はありますが、中にはfloatタイプもやっています(Unityをやるべきだと感じているので). 機能面では,マルチユーザインタラクションをテストするために,Demo上で4個のSocket 4個のスレッドを開いてデータを受け取った.サービス側がユーザに離脱を通知する機能を実現した. 本体には、ワードライブラリを追加する必要があります.中国語を表示できません. プロジェクトディレクトリ:
次のコードは次のとおりです.
クライアントコード:
サーバ側コードJava:
とても简単なdemo、一定の拡張性があって、工事のダウンロードを必要として见て、リンクをダウンロードします
http://download.csdn.net/detail/genius840215/4187126
次のコードは次のとおりです.
クライアントコード:
using UnityEngine;
using System;
using System.Collections;
using LSocket.Net;
using LSocket.Type;
using LSocket.cmd;
public class SocketDemo : MonoBehaviour
{
public UnitySocket[] socket;
public String[] textAreaString;
public String[] textFieldString;
public GUISkin mySkin;
// Use this for initialization
void Start()
{
socket = new UnitySocket[4];
textAreaString = new String[12];
for (int i = 0; i < 12; i++)
{
textAreaString[i] = "";
}
textFieldString = new String[4];
for(int i=0;i<4;i++){
textFieldString[i] = "";
}
}
// Update is called once per frame
void Update()
{
}
void OnGUI()
{
GUI.skin = mySkin;
for (int i = 0; i < 4; i++)
{
String s = textAreaString[i * 3] + "
" + textAreaString[i * 3 + 1] + "
" + textAreaString[i * 3 + 2];
GUI.TextArea(new Rect(i % 2 * Screen.width / 2, i / 2 * (Screen.height / 2) + 50, 100, 60), s);
textFieldString[i] = GUI.TextField(new Rect(i % 2 * Screen.width / 2+50, i / 2 * (Screen.height / 2), 100, 20), textFieldString[i]);
if (GUI.Button(new Rect(i % 2 * Screen.width / 2, i / 2 * (Screen.height / 2), 40, 20), " "))
{
socket[i] = null;
socket[i] = new UnitySocket();
socket[i].SocketConnection("192.168.0.8", 10000, this, i);
socket[i].DoLogin(textFieldString[i]);
}
else if (GUI.Button(new Rect(i % 2 * Screen.width / 2, i / 2 *( Screen.height / 2) + 25, 40, 20), " "))
{
if (socket[i] != null)
{
socket[i].close();
socket[i] = null;
}
}
}
if (GUI.Button(new Rect(Screen.width - 60, Screen.height - 30, 60, 30), " ")) {
Application.Quit();
}
}
}
namespace LSocket.Net
{ /**
*
* @author feng ,qq:313785443
* @date 2010-12-23
*
*/
// : c# socket
using UnityEngine;
using System;
using System.Net.Sockets;
using System.Net;
using System.Collections;
using System.Text;
using System.Threading;
using LSocket.Type;
using LSocket.cmd;
class SocketThread
{
UnitySocket socket;
SocketDemo demo;
int idx;
public SocketThread(UnitySocket socket, SocketDemo demo, int idx)
{
this.socket = socket;
this.demo = demo;
this.idx = idx;
}
public void run()
{
while (true)
{
try
{
String s = socket.ReceiveString();
demo.textAreaString[idx * 3] = demo.textAreaString[idx * 3 + 1];
demo.textAreaString[idx * 3 + 1] = demo.textAreaString[idx * 3 + 2];
demo.textAreaString[idx * 3 + 2] = s;
MonoBehaviour.print(s + " " + idx);
}
catch (Exception e)
{
MonoBehaviour.print(e.ToString());
socket.t.Abort();
}
}
}
}
public class UnitySocket
{
public Socket mSocket = null;
public Thread t=null;
private SocketThread st=null;
public SocketDemo demo=null;
public UnitySocket()
{
}
public void SocketConnection(string LocalIP, int LocalPort,SocketDemo demo,int idx)
{
this.demo=demo;
mSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
try
{
IPAddress ip = IPAddress.Parse(LocalIP);
IPEndPoint ipe = new IPEndPoint(ip, LocalPort);
mSocket.Connect(ipe);
st =new SocketThread(this, demo, idx);
t = new Thread(new ThreadStart(st.run));
t.Start();
}
catch (Exception e)
{
MonoBehaviour.print(e.ToString());
}
}
public void close(){
mSocket.Close(0);
mSocket=null;
}
public void DoLogin(String userName){
try
{
Send(CommandID.LOGIN);
Send(userName);
}catch(Exception e){
MonoBehaviour.print(e.ToString());
}
}
public void Send(float data){
byte[] longth = TypeConvert.getBytes(data, true);
mSocket.Send(longth);
}
public float ReceiveFloat()
{
byte[] recvBytes = new byte[4];
mSocket.Receive(recvBytes, 4, 0);//
float data = TypeConvert.getFloat(recvBytes, true);
return data;
}
public void Send(short data)
{
byte[] longth=TypeConvert.getBytes(data,true);
mSocket.Send(longth);
}
public void Send(long data)
{
byte[] longth=TypeConvert.getBytes(data,true);
mSocket.Send(longth);
}
public void Send(int data)
{
byte[] longth=TypeConvert.getBytes(data,true);
mSocket.Send(longth);
}
public void Send(string data)
{
byte[] longth=Encoding.UTF8.GetBytes(data);
Send(longth.Length);
mSocket.Send(longth);
}
public short ReceiveShort()
{
byte[] recvBytes = new byte[2];
mSocket.Receive(recvBytes,2,0);//
short data=TypeConvert.getShort(recvBytes,true);
return data;
}
public int ReceiveInt()
{
byte[] recvBytes = new byte[4];
mSocket.Receive(recvBytes,4,0);//
int data=TypeConvert.getInt(recvBytes,true);
return data;
}
public long ReceiveLong()
{
byte[] recvBytes = new byte[8];
mSocket.Receive(recvBytes,8,0);//
long data=TypeConvert.getLong(recvBytes,true);
return data;
}
public String ReceiveString()
{
int length = ReceiveInt();
MonoBehaviour.print("Stringlen="+length);
byte[] recvBytes = new byte[length];
mSocket.Receive(recvBytes,length,0);//
String data = Encoding.UTF8.GetString(recvBytes);
return data;
}
}
}
namespace LSocket.Type
{
using UnityEngine;
using System.Collections;
public class TypeConvert
{
public TypeConvert()
{
}
public static byte[] getBytes(float s,bool asc){
int buf = (int)(s * 100);
return getBytes(buf,asc);
}
public static float getFloat(byte[] buf,bool asc){
int i=getInt(buf,asc);
float s=(float)i;
return s/100;
}
public static byte[] getBytes(short s, bool asc)
{
byte[] buf = new byte[2];
if (asc)
{
for (int i = buf.Length - 1; i >= 0; i--)
{
buf[i] = (byte)(s & 0x00ff);
s >>= 8;
}
}
else
{
for (int i = 0; i < buf.Length; i++)
{
buf[i] = (byte)(s & 0x00ff);
s >>= 8;
}
}
return buf;
}
public static byte[] getBytes(int s, bool asc)
{
byte[] buf = new byte[4];
if (asc)
for (int i = buf.Length - 1; i >= 0; i--)
{
buf[i] = (byte)(s & 0x000000ff);
s >>= 8;
}
else
for (int i = 0; i < buf.Length; i++)
{
buf[i] = (byte)(s & 0x000000ff);
s >>= 8;
}
return buf;
}
public static byte[] getBytes(long s, bool asc)
{
byte[] buf = new byte[8];
if (asc)
for (int i = buf.Length - 1; i >= 0; i--)
{
buf[i] = (byte)(s & 0x00000000000000ff);
s >>= 8;
}
else
for (int i = 0; i < buf.Length; i++)
{
buf[i] = (byte)(s & 0x00000000000000ff);
s >>= 8;
}
return buf;
}
public static short getShort(byte[] buf, bool asc)
{
if (buf == null)
{
//throw new IllegalArgumentException("byte array is null!");
}
if (buf.Length > 2)
{
//throw new IllegalArgumentException("byte array size > 2 !");
}
short r = 0;
if (!asc)
for (int i = buf.Length - 1; i >= 0; i--)
{
r <<= 8;
r |= (short)(buf[i] & 0x00ff);
}
else
for (int i = 0; i < buf.Length; i++)
{
r <<= 8;
r |= (short)(buf[i] & 0x00ff);
}
return r;
}
public static int getInt(byte[] buf, bool asc)
{
if (buf == null)
{
// throw new IllegalArgumentException("byte array is null!");
}
if (buf.Length > 4)
{
//throw new IllegalArgumentException("byte array size > 4 !");
}
int r = 0;
if (!asc)
for (int i = buf.Length - 1; i >= 0; i--)
{
r <<= 8;
r |= (buf[i] & 0x000000ff);
}
else
for (int i = 0; i < buf.Length; i++)
{
r <<= 8;
r |= (buf[i] & 0x000000ff);
}
return r;
}
public static long getLong(byte[] buf, bool asc)
{
if (buf == null)
{
//throw new IllegalArgumentException("byte array is null!");
}
if (buf.Length > 8)
{
//throw new IllegalArgumentException("byte array size > 8 !");
}
long r = 0;
if (!asc)
for (int i = buf.Length - 1; i >= 0; i--)
{
r <<= 8;
r |= (buf[i] & 0x00000000000000ff);
}
else
for (int i = 0; i < buf.Length; i++)
{
r <<= 8;
r |= (buf[i] & 0x00000000000000ff);
}
return r;
}
}
}
namespace LSocket.cmd
{
public class CommandID
{
/** **/
public static int LOGIN = 1001;
}
}
サーバ側コードJava:
package com.unity.socket;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
public class SocketServer {
private HashMap userMap;
public SocketServer(){
userMap=new HashMap();
}
public static void main(String[] args){
new SocketServer().startServer();
}
public void startServer()
{
try
{
ServerSocket serverSocket = new ServerSocket(10000);
System.out.println(" ");
while (true){
Socket socket = serverSocket.accept();
System.out.println(" ");
new UserThread(socket,userMap).start();
}
}catch (Exception e){
System.out.println(" !" + e);
}
}
}
package com.unity.socket;
import java.net.Socket;
public class User {
private String name;
private Socket socket;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Socket getSocket() {
return socket;
}
public void setSocket(Socket socket) {
this.socket = socket;
}
}
package com.unity.socket;
import java.io.*;
import java.net.Socket;
import java.util.Iterator;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.util.HashMap;
public class UserThread extends Thread{
/** **/
public static final int ERROR = 0;
/** **/
public static final int LOGIN = 1001;
private Socket socket;
private HashMap userMap;
private User user;
private ByteArrayOutputStream byteOutput;
private DataOutputStream output;
private DataInputStream input;
public UserThread(Socket socket,HashMap userMap){
this.socket=socket;
this.userMap=userMap;
}
// 2 output
private void initOutput()
{
byteOutput = new ByteArrayOutputStream();
output = new DataOutputStream(byteOutput);
}
public void sendAllUser(byte[] bytes) throws Exception
{
for(Iterator it = userMap.values().iterator(); it.hasNext();)
{
sendMessage(it.next().getSocket(),bytes);
}
}
public void sendMessage(Socket socket,byte[] bytes) throws Exception
{
DataOutputStream dataOutput = new DataOutputStream(socket.getOutputStream());
dataOutput.write(bytes);
dataOutput.flush();
}
public short readShort()throws IOException{
byte[] buf=new byte[2];
input.read(buf);
return ConvertType.getShort(buf,true);
}
public int readInt()throws IOException{
byte[] buf=new byte[4];
input.read(buf);
return ConvertType.getInt(buf, true);
}
public long readLong()throws IOException{
byte[] buf=new byte[8];
input.read(buf);
return ConvertType.getLong(buf, true);
}
public float readFloat()throws IOException{
byte[] buf=new byte[4];
input.read(buf);
return ConvertType.getFloat(buf, true);
}
public String readString()throws IOException{
int length=readInt();
byte[] buf=new byte[length];
input.read(buf);
return new String(buf);
}
public void run(){
try{
input = new DataInputStream(socket.getInputStream()) ;
while (true){
int cmd=0;
cmd=readInt();
System.out.println(" :"+cmd);
if(cmd==ERROR){ //
userMap.remove(user.getName());
Message msg=new Message();
msg.writeString(user.getName()+" ");
System.out.println(user.getName()+" ");
try{
sendAllUser(msg.getBuff().array());
}catch (Exception ex){
System.out.println("sendAllUserErr: "+ex.toString());
}
break;
}
switch (cmd){
case LOGIN:
System.out.println(" ");
String userName = readString();
user = new User();
user.setName(userName);
user.setSocket(socket);
System.out.println(userName);
if(userMap.containsKey(userName)) {
Message msg=new Message();
msg.writeString(" ");
sendMessage(socket,msg.getBuff().array());
msg.clear();
msg=null;
}else{
System.out.println(" :" + userName);
userMap.put(userName, user);
initOutput();
Message msg=new Message();
msg.writeString(" ");
sendMessage(socket,msg.getBuff().array());
msg.clear();
msg=null;
}
break;
}
}
}catch (Exception e){
e.printStackTrace();
userMap.remove(user.getName());
Message msg=new Message();
msg.writeString(user.getName()+" ");
System.out.println(user.getName()+" ");
try{
sendAllUser(msg.getBuff().array());
}catch (Exception ex){
System.out.println("sendAllUserErr: "+ex.toString());
}
}
}
}
package com.unity.socket;
import java.nio.ByteBuffer;
import com.unity.socket.ConvertType;
public class Message {
private ByteBuffer buf;
public Message(){
buf=ByteBuffer.allocate(0);
}
public ByteBuffer getBuff(){
return buf;
}
public void clear(){
buf.clear();
}
public void addSize(int len){
ByteBuffer tmpbuf=ByteBuffer.allocate(buf.capacity()+len);
buf=null;
buf=tmpbuf;
}
public void writeByte(byte b){
addSize(1);
buf.put(b);
}
public void write(byte[] b){
addSize(b.length);
buf.put(b);
}
public void writeShort(short b){
addSize(2);
buf.put(ConvertType.getBytes(b,true));
}
public void writeInt(int b){
addSize(4);
buf.put(ConvertType.getBytes(b,true));
}
public void writeLong(long b){
addSize(8);
buf.put(ConvertType.getBytes(b,true));
}
public void writeFloat(float b){
addSize(4);
buf.put(ConvertType.getBytes(b,true)) ;
}
public void writeString(String s){
byte[] b= new byte[200];
b=s.getBytes();
addSize(4+b.length);
buf.put(ConvertType.getBytes(b.length,true));
buf.put(s.getBytes());
}
}
package com.unity.socket;
public class ConvertType
{
public ConvertType()
{
}
public final static byte[] getBytes(float s,boolean asc){
int buf=(int)(s*100);
return getBytes(buf,asc);
}
public final static float getFloat(byte[] buf,boolean asc){
int i=getInt(buf,asc);
float s=(float)i;
return s/100;
}
public final static byte[] getBytes(short s, boolean asc)
{
byte[] buf = new byte[2];
if (asc)
{
for (int i = buf.length - 1; i >= 0; i--)
{
buf[i] = (byte) (s & 0x00ff);
s >>= 8;
}
}
else
{
for (int i = 0; i < buf.length; i++)
{
buf[i] = (byte) (s & 0x00ff);
s >>= 8;
}
}
return buf;
}
public final static byte[] getBytes(int s, boolean asc) {
byte[] buf = new byte[4];
if (asc)
for (int i = buf.length - 1; i >= 0; i--) {
buf[i] = (byte) (s & 0x000000ff);
s >>= 8;
}
else
for (int i = 0; i < buf.length; i++) {
buf[i] = (byte) (s & 0x000000ff);
s >>= 8;
}
return buf;
}
public final static byte[] getBytes(long s, boolean asc) {
byte[] buf = new byte[8];
if (asc)
for (int i = buf.length - 1; i >= 0; i--) {
buf[i] = (byte) (s & 0x00000000000000ff);
s >>= 8;
}
else
for (int i = 0; i < buf.length; i++) {
buf[i] = (byte) (s & 0x00000000000000ff);
s >>= 8;
}
return buf;
}
public final static short getShort(byte[] buf, boolean asc)
{
if (buf == null)
{
throw new IllegalArgumentException("byte array is null!");
}
if (buf.length > 2)
{
throw new IllegalArgumentException("byte array size > 2 !");
}
short r = 0;
if (!asc)
for (int i = buf.length - 1; i >= 0; i--) {
r <<= 8;
r |= (buf[i] & 0x00ff);
}
else
for (int i = 0; i < buf.length; i++) {
r <<= 8;
r |= (buf[i] & 0x00ff);
}
return r;
}
public final static int getInt(byte[] buf, boolean asc) {
if (buf == null) {
throw new IllegalArgumentException("byte array is null!");
}
if (buf.length > 4) {
throw new IllegalArgumentException("byte array size > 4 !");
}
int r = 0;
if (!asc)
for (int i = buf.length - 1; i >= 0; i--) {
r <<= 8;
r |= (buf[i] & 0x000000ff);
}
else
for (int i = 0; i < buf.length; i++) {
r <<= 8;
r |= (buf[i] & 0x000000ff);
}
return r;
}
public final static long getLong(byte[] buf, boolean asc) {
if (buf == null) {
throw new IllegalArgumentException("byte array is null!");
}
if (buf.length > 8) {
throw new IllegalArgumentException("byte array size > 8 !");
}
long r = 0;
if (!asc)
for (int i = buf.length - 1; i >= 0; i--) {
r <<= 8;
r |= (buf[i] & 0x00000000000000ff);
}
else
for (int i = 0; i < buf.length; i++) {
r <<= 8;
r |= (buf[i] & 0x00000000000000ff);
}
return r;
}
}
とても简単なdemo、一定の拡張性があって、工事のダウンロードを必要として见て、リンクをダウンロードします
http://download.csdn.net/detail/genius840215/4187126