服务端
using System;
using System.Collections.Generic;
using System.Net;
using System.Text;
using System.Net.Sockets;
using System.IO;
namespace ASyncSocketServer
{
class ClientInfo//客户端信息类
{
const int BUFFER_SIZE = 1024;//缓冲区的大小
public Socket client;//当前客户端保持连接的套接字
public byte[] buffer;//这个套接字接收到的数据
public ClientInfo(Socket client)
{
this.client = client;
buffer = new byte[BUFFER_SIZE];
}
public string getInfo()//返回这个客户端的ip和端口字符串
{
return client.RemoteEndPoint.ToString();
}
}
class Program
{
//所有的连接套接字的信息
static List<ClientInfo> clientInfos = new List<ClientInfo>();
static void Main(string[] args)
{
Socket listenSocket = null;
try {
IPAddress ipAddr = IPAddress.Parse("127.0.0.1");
Console.WriteLine("ip地址创建成功!");
IPEndPoint ipEP = new IPEndPoint(ipAddr, 7777);
Console.WriteLine("ip终结点创建成功!");
listenSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
Console.WriteLine("监听套接字创建成功!");
listenSocket.Bind(ipEP);
Console.WriteLine("绑定成功!");
listenSocket.Listen(5);
Console.WriteLine("监听成功!");
//开始承认连接
listenSocket.BeginAccept(new AsyncCallback(Accept), listenSocket);
Console.WriteLine("服务器启动成功!");
}catch(Exception e)
{
Console.WriteLine("服务器启动过程出错了!" + e.Message);
if (listenSocket != null) { }
listenSocket.Close();
}
Console.ReadLine();
}
static void Accept(IAsyncResult iar)
{
Console.WriteLine("Accept:有连接了!");
//得到监听的套接字
Socket listenSocket = iar.AsyncState as Socket;
try {
//确认这次连接
Socket client = listenSocket.EndAccept(iar);
Console.WriteLine("Accept:确认连接成功!");
ClientInfo ci = new ClientInfo(client);
//保存这个套接字
clientInfos.Add(ci);
Console.WriteLine("Accept:现在一共有" + clientInfos.Count);
//接收这个客户端发来的数据
client.BeginReceive(ci.buffer, 0, ci.buffer.Length, SocketFlags.None, new AsyncCallback(Receive), ci);
Console.WriteLine("Accept:开始接收这个客户端的信息!");
//广播出去
//继续承认连接
listenSocket.BeginAccept(new AsyncCallback(Accept), listenSocket);
}
catch(Exception e)
{
Console.WriteLine("Accept:有错误了!"+e.Message);
}
}
static void Receive(IAsyncResult iar)
{
//得到当前发数据的客户端信息
ClientInfo ci = iar.AsyncState as ClientInfo;
try {
//确认接收
int len = ci.client.EndReceive(iar);
//判断客户端是否已经断开
if (len <= 0)
{
Console.WriteLine(ci.getInfo() + "Receive:这个客户端主动断开了!");
//移除这个客户端的信息
ci.client.Close();
clientInfos.Remove(ci);
//广播这个客户走的信息给其它
return;
}
string str = Encoding.UTF8.GetString(ci.buffer, 0, len);
Console.WriteLine(ci.getInfo() + "Receive:来数据了:" + str);
//分析客户来的数据
analyData(str,ci);
//广播信息
foreach (ClientInfo c in clientInfos)
{
//判断是否是自己
c.client.Send(Encoding.UTF8.GetBytes(str));
}
}catch(Exception e)
{
string str = e.Message;
Console.WriteLine( "Receive:有错误了!"+str);
//if (str.Contains("远程主机强迫关闭了一个现有的连接"))
//{
ci.client.Close();
clientInfos.Remove(ci);
//}
return;
}
//继续接收这个客户端发来的数据
ci.client.BeginReceive(ci.buffer, 0, ci.buffer.Length, SocketFlags.None, new AsyncCallback(Receive), ci);
}
static void analyData(string str,ClientInfo ci)
{
//分割消息
string[] elements= str.Split(new string[] { "$^*" }, StringSplitOptions.RemoveEmptyEntries);
if (elements != null && elements.Length>0)//确实是得到了一个数组,而且有元素
{
int num = 0;
try
{
num = int.Parse(elements[0]);//转换命令码
}catch(Exception e)
{
num = -1;
}
if (num >= 100)//是一个有效的消息
{
switch (num)
{
case 100:
//处理登录
//得到已经注册的用户信息
string[] users = File.ReadAllLines("db.txt");
string uname = elements[1];//要登录的用户名
string upass = elements[2];//要登录的密码
bool isRegister = false;
foreach(string s in users)//遍历每个用户信息
{
//拆分到数组
string[] xxs = s.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
//如果这个用户存在
if (xxs[0].Equals(uname) && xxs[1].Equals(upass))
{
isRegister = true;
break;
}
}
if (isRegister)
{
//告诉客户端登陆成功
string temp = "101$^*" + "ok" + "$^*" + "ok";
ci.client.Send(Encoding.UTF8.GetBytes(temp));
}
else
{
//告诉客户端登陆失败
string temp = "102$^*" + "err" + "$^*" + "err";
ci.client.Send(Encoding.UTF8.GetBytes(temp));
}
break;
}
}
}
}
}
}
客户端
using UnityEngine;
using System.Net;
using System.Net.Sockets;
using System.Text;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
public class Networks : MonoBehaviour {
public List<string> messages = new List<string>();
private Socket socket;
private byte[] buf = new byte[1024];
public bool isLogin = false;//代表是否登录了
void OnApplicationQuit()//应用的关闭事件
{
if (socket != null)
{
Disconn();
}
}
public bool Conn()
{
try {
IPAddress ip = IPAddress.Parse("127.0.0.1");
IPEndPoint ipep = new IPEndPoint(ip, 7777);
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket.Connect(ipep);
socket.BeginReceive(buf, 0, buf.Length, SocketFlags.None, new AsyncCallback(receive), socket);
}catch(Exception e)
{
return false;
}
return true;
}
void receive(IAsyncResult iar)
{
int len = socket.EndReceive(iar);
string str = Encoding.UTF8.GetString(buf, 0, len);
print(str);
messages.Add( str);
socket.BeginReceive(buf, 0, buf.Length, SocketFlags.None, new AsyncCallback(receive), socket);
}
public void Disconn()
{
if (socket != null)
{
socket.Shutdown(SocketShutdown.Both);
socket.Close();
socket = null;
}
}
public void send(string str)
{
socket.Send(Encoding.UTF8.GetBytes(str));
}
void Update()
{
if (messages.Count > 0)
{
string str = messages[0];
//分析这个消息
analyData(str);
messages.RemoveAt(0);
}
}
void analyData(string str)
{
//分割消息
string[] elements = str.Split(new string[] { "$^*" }, StringSplitOptions.RemoveEmptyEntries);
if (elements != null && elements.Length > 0)//确实是得到了一个数组,而且有元素
{
int num = 0;
try
{
num = int.Parse(elements[0]);//转换命令码
}
catch (Exception e)
{
num = -1;
}
if (num >= 100)//是一个有效的消息
{
if (isLogin)//已经登录
{
}
else//登录中
{
if (num == 101)//登录成功了
{
SceneManager.LoadScene("Game");
isLogin = true;
}
else if (num == 102)//登录失败了
{
Text msgText = GameObject.Find("MsgText").GetComponent<Text>();
msgText.text = "***登录失败,用户名或密码错误!***";
Disconn();//断开连接
//得到登录的按钮
Button loginButton = GameObject.Find("LoginButton").GetComponent<Button>();
//解锁按钮
loginButton.enabled = true;
}
}
}
}
}
}
登录按钮
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System.Net;
public class onLick : MonoBehaviour {
public void OnClick()
{
//得到账号
string uname = GameObject.Find("UnameInputField").GetComponent<InputField>().text;
//得到密码
string upass = GameObject.Find("UpassInputField").GetComponent<InputField> ().text;
//得到提示信息
Text msg = GameObject.Find("MsgText").GetComponent<Text>();
//有效性验证
uname = uname.Trim();//Trim剔除两端的空格
upass = upass.Trim();
msg.text = "";
if (uname.Length <= 0)
{
//清空账号
GameObject.Find ("UnameInputField").GetComponent<InputField> ().text = "";
msg.text = "账号不能为空,必须填写";
return;
}
if (upass.Length <= 0)
{
//清空密码
GameObject.Find ("UpassInputField").GetComponent<InputField> ().text = "";
msg.text = "密码不能为空,必须填写";
return;
}
//连接服务器
Button login = GameObject.Find("LoginButton").GetComponent<Button>();
login.enabled = false;
Networks net = GameObject.Find ("Net").GetComponent<Networks> ();
if (net.Conn ()) {
msg.text = "连接服务器成功开始登录";
} else {
msg.text = "连接服务器失败,请重新登录";
}
//发登录的消息
}
}
储存信息
string[] str = File.ReadAllLines("a.txt");