用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