游戏开发服务器入门笔记2-简易聊天室(异步服务器)

客户端:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Net.Sockets;
using UnityEngine.UI;
using System;

public class Echo : MonoBehaviour {
    /// <summary>
    /// 定义套接字
    /// </summary>
    Socket F_socket;
    /// <summary>
    /// UI文本输入
    /// </summary>
    public InputField F_input;
    public Text F_text;
    /// <summary>
    /// 接收缓冲区
    /// </summary>
    byte[] readBuff = new byte[1024];
    string recvStr = "";

    /// <summary>
    /// 连接网络
    /// </summary>
    public void Collection()
    {
        //配置地址族、套接字类型、协议
        //地址族:InterNetwork-IPv4,InterNetworkV6-IPv6
        //套接字类型:通常使用Stream,Dgram、Raw、RDM、Seqpacket、Unknown
        //协议:通常使用TCP,GGP、ICMP、ICMPv6、IP、Internet、PARC、RAW、UDP、Unknown、Unspecified
        F_socket = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
        //连接服务器
        F_socket.BeginConnect("10.32.3.208",8888, ConnectCallback, F_socket);
    }
    /// <summary>
    /// connect回调
    /// </summary>
    /// <param name="ar"></param>
    public void ConnectCallback(IAsyncResult ar)
    {
        try
        {
            Socket socket = (Socket)ar.AsyncState;
            socket.EndConnect(ar);
            Debug.Log("Connection successful");
            socket.BeginReceive(readBuff,0,1024,0, ReceiveCallback, F_socket);
        }
        catch(SocketException e)
        {
            Debug.Log("Socket Connect fail"+e.ToString());
        }
    }
    /// <summary>
    /// receive回调
    /// </summary>
    public void ReceiveCallback(IAsyncResult ar) {
        try
        {
            Socket socket = (Socket)ar.AsyncState;
            int count = socket.EndReceive(ar);
            //将字节流转化为字符串
            recvStr = System.Text.Encoding.Default.GetString(readBuff, 0, count);
            socket.BeginReceive(readBuff, 0, 1024, 0, ReceiveCallback, F_socket);
        }
        catch(SocketException e)
        {
            Debug.Log("Socket Receiver fail"+e.ToString());
        }
    }


    /// <summary>
    /// 发送文字
    /// </summary>
    public void Send()
    {
        //获取发送的文本
        string sendStr = F_input.text;
        //文本转换为byte串
        byte[] sendBytes = System.Text.Encoding.Default.GetBytes(sendStr);
        //发送字节流
        F_socket.BeginSend(sendBytes,0,sendBytes.Length,0,SendCallback,F_socket);
    }
    /// <summary>
/// 回调send
/// </summary>
/// <param name="ar"></param>
    public void SendCallback(IAsyncResult ar)
    {
        try
        {
            Socket socket = (Socket)ar.AsyncState;
            int count = socket.EndSend(ar);
            string s = System.Text.Encoding.Default.GetString(readBuff,0,count);
            recvStr = s + "\n" + recvStr;
        }
        catch (SocketException e)
        {
            Debug.Log("Socket send fail"+e.ToString());
        }
    }

    private void Update()
    {
        //实时更新服务器反馈消息记录
        F_text.text = recvStr;
    }
}

服务器:

using System;
using System.Net;
using System.Net.Sockets;
using System.Collections.Generic;

namespace EchoServer
{
	//用户状态
	class ClientState{
		//套接字
		public Socket socket;
		//字节流
		public byte[] readBuff=new byte[1024];
	}
	class MainClass
	{
		//监听socket
		static Socket listenfd ;
		//客户端socket及状态信息
		static Dictionary<Socket,ClientState>clients=new Dictionary<Socket, ClientState>();

		public static void Main (string[] args)
		{

			listenfd= new Socket (AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);

			//设置套接字和IP端口,并进行绑定
			IPAddress ipAdr = IPAddress.Parse ("10.32.3.208");
			IPEndPoint ipEP = new IPEndPoint (ipAdr,8888);
			listenfd.Bind (ipEP);

			//开启监听,数字表示限制的连接数
			listenfd.Listen (0);
			Console.WriteLine ("服务器启动成功");

			listenfd.BeginAccept (AcceptCallback,listenfd);
			Console.ReadLine ();
		}
		//accept回调
		public static void AcceptCallback(IAsyncResult ar){
			try{
				Console.WriteLine ("[服务器]接收");
				Socket listenfd=(Socket)ar.AsyncState;
				Socket clientfd=listenfd.EndAccept(ar);

				ClientState state=new ClientState();
				state.socket=clientfd;
				clients.Add(clientfd,state);
				clientfd.BeginReceive(state.readBuff,0,1024,0,ReceiveCallback,state);
				listenfd.BeginAccept(AcceptCallback,listenfd);
			}
			catch(SocketException e){
				Console.WriteLine ("Socket Accept fail"+e.ToString());
			}
		}
		//receive回调
		public static void ReceiveCallback(IAsyncResult ar){
			try{
				ClientState state=(ClientState)ar.AsyncState;
				Socket clientfd=state.socket;
				int count=clientfd.EndReceive(ar);
				//客户端为0
				if(count==0){
					clientfd.Close();
					clients.Remove(clientfd);
					Console.WriteLine ("Socket Close");
					return;
				}
				string recvStr=System.Text.Encoding.Default.GetString(state.readBuff,0,count);
				byte[] sendBytes=System.Text.Encoding.Default.GetBytes("mode in LFF:\n"+recvStr);
				//广播
				foreach(ClientState s in clients.Values){
					s.socket.Send(sendBytes);
				}
				clientfd.BeginReceive(state.readBuff,0,1024,0,ReceiveCallback,state);
			}
			catch(SocketException e){
				Console.WriteLine ("Socket Receive fail"+e.ToString());
			}
		}
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
一个用于Web游戏中的即时聊天代码 使用内存进行消息投递 支持私聊和供聊 支持统计在线人数 可开多个房间 注意:有人反映这个不能直接使用,在这里特做一下说明 =============================================== 这个程序是从游戏中拿出来的,并不是一个独立的应用程序 发上去的部分是不能直接运行的,发出来的目的只是想给有这方面兴趣的朋友做个参考,因为我自己才做这块的时候确实走了不少弯路 里面有类设计图,类设计图是用powerdesign 12.5设计的 可以通过类设计图看服务端的设计 客户端是一个demo html文件 要运行还需要配数据库,还需要微软的企业库开发包 不了解企业库的可以去这里看看 http://www.codeplex.com/entlib 你也可以修改一下代码让程序不需要访问数据库 访问数据库主要是加载房间信息,你可以在代码里弄几个模拟的房间信息 聊天消息的中专是不依赖数据库的 ====================================== 再次补充说明 这个代码的开发环境为:vs2008+sqlserver2005+微软企业库+net fwk3.5 其实用vs2005+2.0框架也可以,虽然使用的是3.5的框架,但是并没有使用3.5框架的新特性 经检查发现里面确实没有类设计图,也没有服务器端的源代码 现在传上去的这部分只是一个demo,包含客户端和编译过的服务器端代码 非常的抱歉,我将不上源代码和相关设计文件 =========================================================== 目录结构说明 ChatDemo-包含客户端和编译过的服务器端 ChatDemo/ChatDemo.HttpHandler-客户端http处理器(客户端和服务器端的交互就靠这些文件了) ChatDemo/ChatWebDemo-客户端的实现代码 ChatDemo/ChatWebDemo/ServerManager.aspx-此文件可控制服务器的启动和关闭(客户端和服务器端是存在于同一台电脑上测试的,所以在一个工程里) ChatDemo/ChatWebDemo/SelectChatRoom.aspx-可选择进入哪一个聊天室 ChatDemo/ChatWebDemo/Chat.aspx-聊天客户端界面 DinosaurEmpery-包含服务器端的源代码和相关设计文档-数据库文档等 DinosaurEmpery/src-服务端源代码和单元测试相关资料 DinosaurEmpery/src/Chat DinosaurEmpery/src/IChat 这两个才是聊天部分的代码,其它目录为游戏其它部分的代码(只是部分代码,是不能运行的) DinosaurEmpery/using-程序中用引用到到第3方dll(微软企业库)(由于压缩后的结果代码太大,所以删除了里面的内容)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值