用Unity开发网络游戏除了使用Unity自带的Network类之外,比较原始的方法就是使用Socket接口了。本文基于.NET平台的Socket接口,编写了一个UDP协议下的简单程序,实现了类似于Echo的功能。具体为客户端向服务器发送一个信息,服务器返回一个应答。代码如下:

C++编写的服务器端(使用Winsock):

#include <stdio.h>
#include <WinSock2.h>
#pragma comment(lib, "ws2_32.lib") 
using namespace std;
#define DEF_PORT 1234
#define BUF_SIZE 64
int main(int argc, char* argv[])
	WSADATA wsaData;
	SOCKET srvSock = 0;//服务器socket句柄
	sockaddr_in srvAddr,//服务器端地址
				clntAddr;//客户端地址
	unsigned short port = DEF_PORT;//端口号
	int result,//返回结果
		addrLen = sizeof(srvAddr);//地址长度
	char recvBuf[BUF_SIZE];//服务器接收端缓冲区
	char answer[] = "Hello,I'm simplatform server!"; //应答
	//初始化套接字
	WORD socketVersion = MAKEWORD(2, 2);
	if (WSAStartup(socketVersion, &wsaData) != 0) {
		printf("初始化套接字失败!");
		return 0;
	//创建套接字
	srvSock = socket(AF_INET, SOCK_DGRAM, 0);
	if (srvSock == INVALID_SOCKET) {
		printf("Socket error!");
		return 0;
	//为socket绑定一个本地地址
	srvAddr.sin_family = AF_INET;
	srvAddr.sin_port = htons(port);
	srvAddr.sin_addr.S_un.S_addr = INADDR_ANY;
	result = bind(srvSock, (sockaddr*)&srvAddr, addrLen);
	if (result == SOCKET_ERROR) {
		printf("Bind error!");
		closesocket(srvSock);
		return 0;
	printf("[Simplatform Server] 服务器正在运行...\n");
	//主循环
	while (1)
		result = recvfrom(srvSock, recvBuf, BUF_SIZE, 0, (sockaddr*)&clntAddr, &addrLen);
		if (result > 0) {
			recvBuf[result] = 0;
			printf("[Simplatform Server] recv: \"%s\", from %s\r\n",
				recvBuf, inet_ntoa(clntAddr.sin_addr));
			sendto(srvSock, answer, strlen(answer), 0, (sockaddr*)&clntAddr, addrLen);
	closesocket(srvSock);
	WSACleanup();
	return 0;
}
C# .NET客户端:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;
namespace simClient
    class Program
        static void Main(string[] args)
            const int DEF_SIZE = 64;
            const string srvIp = "127.0.0.1"; //服务器IP地址
            Socket clntSock = new Socket(AddressFamily.InterNetwork,
                SocketType.Dgram, ProtocolType.Udp); //创建socket
            IPAddress srvAddr = IPAddress.Parse(srvIp); //服务器IP地址
            IPEndPoint srvIpEnd = new IPEndPoint(srvAddr, 1234); //服务器地址
            EndPoint srvEnd = (EndPoint)srvIpEnd; //必须要经过这个类型转换,EndPoint是一个抽象类
            byte[] msg = Encoding.ASCII.GetBytes("Hello!"); //发送消息
            byte[] recvBuf = new byte[DEF_SIZE]; //接收缓冲区大小
            int result = 0; //接收的字节数
            while (true)
                clntSock.SendTo(msg, srvEnd);
                    result = clntSock.ReceiveFrom(recvBuf, ref srvEnd);
                catch (SocketException e)
                    Console.WriteLine("服务器未启动!");
                    System.Threading.Thread.Sleep(4000); //4s后重新发送请求
                    continue;
                if (result > 0)
                    //控制台输出byte[]数组必须要经过转换。
                    string strResult = System.Text.Encoding.ASCII.GetString(recvBuf);
                    Console.WriteLine("收到应答:{0}", strResult);
                System.Threading.Thread.Sleep(2000); //每隔2s发送一次
            clntSock.Close();
运行结果:

另附:C++版本的客户端代码

#include <WinSock2.h>
#include <stdio.h>
#pragma comment(lib, "ws2_32.lib")
using namespace std;
#define DEF_PORT 1234
#define BUF_SIZE 64
int main(int argc, char* argv[])
	WSADATA wsaData;
	SOCKET clntSock = 0;//客户端SOCKET
	sockaddr_in srvAddr,//服务器端地址 
				fromAddr;//存储发送端的地址
	char *dest = "127.0.0.1", //服务器IP地址
		*sendData = "Hello!";//发送数据
	char recvBuf[BUF_SIZE];//接收缓冲区
	int result, addrLen = sizeof(srvAddr);
	//接收命令行参数
	if (argc == 2) {
		dest = argv[1];
	//初始化套接字
	WORD socketVersion = MAKEWORD(2, 2);
	if (WSAStartup(socketVersion, &wsaData) != 0) {
		printf("初始化失败!");
		return 0;
	//创建socket
	clntSock = socket(AF_INET, SOCK_DGRAM, 0);
	if (clntSock == INVALID_SOCKET) {
		printf("socket error!");
		return 0;
	//设置服务器地址
	srvAddr.sin_family = AF_INET;
	srvAddr.sin_addr.S_un.S_addr = inet_addr(dest);
	srvAddr.sin_port = htons(DEF_PORT);
	if (srvAddr.sin_addr.S_un.S_addr == INADDR_NONE) {
		printf("Invalid Address!\r\n");
		return 0;
	while (1)
		sendto(clntSock, sendData, strlen(sendData), 0, (sockaddr*)&srvAddr, addrLen);
		result = recvfrom(clntSock, recvBuf, BUF_SIZE, 0, (sockaddr*)&fromAddr, &addrLen);
		if (result > 0) {
			recvBuf[result] = 0;
			printf("[Simplatform Client] recv: \"%s\", from %s\r\n",
				recvBuf, inet_ntoa(fromAddr.sin_addr));
		Sleep(2000);
	closesocket(clntSock);
	WSACleanup();
	return 0;

参考文献:

1. 《Winsock网络编程经络》

2. MSDN:https://msdn.microsoft.com/zh-cn/library/system.net.sockets(v=vs.110).aspx

用Unity开发网络游戏除了使用Unity自带的Network类之外,比较原始的方法就是使用Socket接口了。本文基于.NET平台的Socket接口,编写了一个UDP协议下的简单程序,实现了类似于Echo的功能。具体为客户端向服务器发送一个信息,服务器返回一个应答。代码如下:C++编写的服务器端(使用Winsock):#include #include #pragma comm