Socket(套接字)用于描述IP地址和端口,是一个通信链的句柄,可以用来实现不同虚拟机或不同计算机之间的通信。网络中的主机一般会运行多个服务器,每个服务器上的每一种服务都会打开一个Socket并绑定到一个端口,不同端口对应着不同的服务。IP对应着网络上的计算机,而端口则对应着计算机上某个具体的进程或服务。就好比邮寄信件时,地址代表一个具体的居民房,人名对应着具体的居住其中的一个人,邮递员根据地址和人名,就能把信件准确地寄出去。
根据连接启动的方式及本地套接字要连接的目标,套接字之间的连接可以分为服务器监听、客户端请求、连接确认三个步骤。
1、服务器监听
服务器端套接字只需要在程序启动之后处于等待连接的状态,并实时监控网络状态,等待其他客户端套接字的连接。
2、客户端请求
客户端套接字需要先创建一个套接字,并在套接字中描述服务器套接字的信息(IP地址和端口号),然后在向服务器套接字提出连接请求。
3、连接确认
当服务器端套接字监听或收到客户端套接字的连接请求时,就会响应客户端套接字的请求,建立一个新的线程,把服务器套接字的描述发给客户端,一旦客户端确认了此描述,连接就建立好了。而服务器端套接字继续处于监听状态,接受其他客户端套接字的连接请求。
以下代码是JAVA后台和Unity C#前台的简单TCP通信
TCP服务端-JAVA
package com.servlet;
import java.io.IOEXception;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketAddress;
public class TestSocket{
public static void main(String[] args)
{
run();
}
public static void run()
{
//Socket 制定端口号为0-65535,不能与其他进程端口号冲突,否则启动时程序会报端口占用的错误
int serbPort=;
//创建服务端Socket
ServerSocket serverSocket=null;
int recvMsgSize=;
//接收字节缓冲数组
byte[] receivBuf=new byte[];
try{
serverSocket=new ServerSocket(servPort);
//处理完一个客户端请求之后再次进入等待状态
while(true)
{
//至此,程序将一直等待客户端连接,直到有客户端接入代码才能继续执行
System.out.println("服务端已启动,绑定端口"+servPort);
Socket clientSocket=serverSocket.accept();
SocketAddress clientAddress=clientSocket.getRemoteSocketAddress();
System.out.println("收到客户端连接,ip"+clientAddress);
InputStream in=clientSocket.getInputStream();
OutputStream out=clientSocket.getOutputStream();
//接收客户端发来的数据,并原样返回客户端
while((recvMsgSize=in.read(receivBuf))!=-){
String receivedData=new String(receivBuf.toString());
System.out.println(receivedData);
out.write(receivBuf,,recvMsgSize);
}
//释放Socket资源
clientSocket.close();
}
}catch(IOException e)
{
e.printStackTrace();
}
}
}
TCP Unity C#客户端
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Net;
using System.Net.Sockets;
using System;
using System.Text;
public class MySocket : MonoBehaviour{
void Start(){
string host="localhost";//此处是ip地址
int port =;
string sendMsg="send data form client";
byte[] buffer=Encoding.Unicode.GetBytes(sendMsg);//把string 数据转码为byte型数据
}
public static void Connet(string sever,int servPort,byte[] data){
TcpClient client=null;
try{
client=new TcpClient(sever,servPort);
Debug.Log("连接服务器并发送数据");
NetworkStream streamToServer=client.GetStream();//获得客户端的流
streamToServer.Write(data,,data.Lenth);//将转换号的二进制数据流写入流中并发送
//接收数据
//目前收到的总字节长度
int totalBytesRcvd=;
//最后一次读取的字节长度
int bytesRcvd;
//将服务器返回消息读到data字节数组中
while(totalBytesRcvd<data.Length)
{
bytesRcvd=streamToServer.Read(data,totalBytesRcvd,data.Length-totalBytesRcvd);
if(bytesRcvd==-)
{
throw new SocketException();
}
totalBytesRcvd+=bytesRcvd;
}
string str=Encoding.Unicode.GetString(data,,data.Length);
Debug.Log("接收的数据:"+str);
}
catch(Exception ex)
{
Debug.Log("客户端异常!");
}
finally{
try{
if(client!=null)
{
client.Close();
}
}
catch(Exceptionm ex)
{
Debug.Log("服务器没有关掉");
}
}
}
}
以上是Java服务端和Unity客户端的简易通信