1. 程式人生 > >c#伺服器, 和Unity端 C#實現非同步互動

c#伺服器, 和Unity端 C#實現非同步互動

public class StateObject
{
    //聊天用的資料
    public Socket workSocket = null;
    public const int BufferSize = 1024;
    public byte[] buffer = new byte[BufferSize];
    public StringBuilder sb = new StringBuilder();
}


伺服器:

using System;  
using System.CodeDom;  
using System.Collections.Generic;  
using System.Linq;  
using System.Net;  
using System.Net.Sockets;  
using System.Text;  
using System.Threading;  
using System.Threading.Tasks;  
  
namespace socketAsyncCallback  
{  
      
    public class StateObject  
    {  
        public Socket WorkSocket = null;  
        public const int  BufferSize = 1024;  
        public byte[] buffer = new byte[BufferSize];  
        public StringBuilder sb = new StringBuilder();  
    }  
  
    class Program  
    {  
        public static ManualResetEvent allDone = new ManualResetEvent(false);  
        private static Socket listener;  
        static void Main(string[] args)  
        {  
            StartListening();  
              
        }  
  
        public static void StartListening()  
        {  
            byte[] bytes = new byte[1024];  
              
            IPAddress ipAddress = IPAddress.Parse("10.2.226.14");  
            int port = 8885;  
            IPEndPoint point = new IPEndPoint(ipAddress, port);  
  
            listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);  
              
            try  
            {  
                listener.Bind(point);  
                listener.Listen(10);  
                listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);  
                //這裡本來是在這裡啟動一個begin的,我把他挪到了AcceptCallback方法裡,這樣就不用讓主執行緒等待了  
                /* 
                while (true) 
                { 
                    allDone.Reset(); 
 
                    Console.WriteLine("Waiting fo a connection..."); 
 
                    listener.BeginAccept(new AsyncCallback(AcceptCallback), listener); 
 
                    allDone.WaitOne(); 
                } 
                 */  
  
            }  
            catch (Exception e)  
            {  
                Console.WriteLine(e.ToString());  
                  
            }  
  
            Console.WriteLine("\n Press Enter to continue");  
            Console.Read();  
  
  
        }  
  
        public static void AcceptCallback(IAsyncResult ar)  
        {  
            listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);  
            Console.WriteLine("come in AcceptCallback");  
            //allDone.Set();  
  
            Socket myListener = (Socket) ar.AsyncState;  
            Socket handler = myListener.EndAccept(ar);  
            //握手,因為我這裡用來連線進來的client 是用的同步的,所以一定要握手才可以,我連線就是用的前面的一篇 socketClient的文章  
            //handler.Send(Encoding.ASCII.GetBytes("server say hello"));  
            //這裡是申創造一個容器, 來傳遞socket  
            StateObject state = new StateObject();  
            state.WorkSocket = handler;  
            handler.BeginReceive(state.buffer, 0, 1024, 0, new AsyncCallback(ReadCallback), state);  
        }  
  
        public static void ReadCallback(IAsyncResult ar)  
        {  
              
            string content = string.Empty;  
            Console.WriteLine("READCALLBACK");  
            StateObject state = (StateObject) ar.AsyncState;  
            Socket handler = state.WorkSocket;

            //handler.Send(Encoding.ASCII.GetBytes("server say hello"));  

            int bytesRead = handler.EndReceive(ar);  
            if (bytesRead > 0)  
            {  
                Console.WriteLine(handler + ":" +Encoding.ASCII.GetString(state.buffer, 0, bytesRead));  
                state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead));  
  
                content = state.sb.ToString();  
                //Console.WriteLine(content);  
                if (content.IndexOf("<EOF>") > -1)  
                {  
                    Console.WriteLine("Read {0} bytes from socket. \n Data: {1}",content.Length, content);  
                    //給客戶端響應,這裡也可以註釋掉,沒有關係  
                    Send(handler, content);  
                }  
                else  
                {  
                    handler.BeginReceive(state.buffer, 0, 1024, 0, new AsyncCallback(ReadCallback),  
                        state);  
                }  
            }  
        }  
  
        private static void Send(Socket handler, string data)  
        {  
            byte[] byteData = Encoding.ASCII.GetBytes(data);  
  
            handler.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), handler);  
        }  
        private static void SendCallback(IAsyncResult ar)  
        {  
            try  
            {  
                Socket handler = (Socket) ar.AsyncState;  
  
                int bytesSend = handler.EndSend(ar);  
                Console.WriteLine("Send {0} bytes to client.", bytesSend);  
                handler.Shutdown(SocketShutdown.Both);  
                handler.Close();  
  
            }  
            catch (Exception e)   
            {  
                Console.WriteLine(e.ToString());  
                 
            }  
        }  
    }  
}  

客戶端:
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using UnityEngine;
using System.Collections;

public class OprationModelGUI : MonoBehaviour {

	// Use this for initialization
    private Vector2 scrollViewPosition = new Vector2(0, 5);
    private string sendMessage = "";
    private string boxMessage = "";
    private Socket clientSocket;
    private Thread reveiveThread;   //開啟執行緒,來接收訊息

	void Start () {
	    StartTalk();
        Receive(clientSocket);
        
	}
	
	// Update is called once per frame
	void Update () {
	   
	}

    void OnGUI()
    {
        //Debug.Log("testModel");
        //GUILayout.Button("ddd");

        GUILayout.Space(300);
        GUILayout.BeginVertical();
        scrollViewPosition = GUILayout.BeginScrollView(scrollViewPosition, GUILayout.Height(120), GUILayout.Width(210));
        GUILayout.Box(boxMessage);
        GUILayout.EndScrollView();

        GUILayout.BeginHorizontal();
        sendMessage = GUILayout.TextField(sendMessage,GUILayout.Width(150));
        if (GUILayout.Button("傳送", GUILayout.Width(50)))
        {
            boxMessage += "\n" + "我說:" + sendMessage;
            Send(clientSocket, sendMessage);
            
            sendMessage = "";
        }
        GUILayout.EndHorizontal();

        GUILayout.EndVertical();

        
    }

    void StartTalk()
    {
        IPAddress ipAddress = IPAddress.Parse("10.2.226.14");
        int port = 8885;
        IPEndPoint remoteEP = new IPEndPoint(ipAddress, port);

        clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        //與目標終端連線
        clientSocket.BeginConnect(remoteEP, new AsyncCallback(ConnectCallback), clientSocket);
        //等待,直到連線程式完成, 在ConnectCallback中適當位置有connectDone.Set()
        
        //傳送資料到遠端終端
        //Send(client, "this is a test");
        
        //client.Shutdown(SocketShutdown.Both);
        //client.Close();
    }

    //連線部分 Callback
    void ConnectCallback(IAsyncResult ar)
    {
        //獲取socket
        Socket client = (Socket) ar.AsyncState;
        //完成連線
        client.EndConnect(ar);


    }
    //資料接收

    void Receive(Socket client)
    {
        //構造容器
        StateObject state = new StateObject();
        state.workSocket = client;

        //從遠端接收資料
        client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);
    }

    void ReceiveCallback(IAsyncResult ar)
    {
        Debug.Log("ReceiveCallBack");
        StateObject state = (StateObject) ar.AsyncState;
        Socket client = state.workSocket;
        
        //從遠端裝置讀取資料
        int bytesRead = client.EndReceive(ar);
        if (bytesRead > 0)
        {
            state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead));
            
            //繼續讀取
            client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);
        
            
        }
        else
        {
            Debug.Log("最後沒有進來");
            if (state.sb.Length > 1)
            {
                Debug.Log(state.sb.ToString());
                boxMessage += "\n" + state.sb.ToString();
            }
        }
        boxMessage += "\n" + state.sb;
    }
    
    //資料傳送
    void Send(Socket client, string data)
    {
        //格式轉換
        byte[] byteData = Encoding.ASCII.GetBytes(data);
        //開始傳送資料到遠端裝置
        client.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), client);
    }

    void SendCallback(IAsyncResult ar)
    {
        Socket client = (Socket) ar.AsyncState;
        //完成資料傳送
        int bytesSent = client.EndSend(ar);

    }


}


相關推薦

c#伺服器 Unity C#實現非同步互動

public class StateObject { //聊天用的資料 public Socket workSocket = null; public const int BufferSize = 1024; public byte[] bu

ROS學習筆記18 (編寫簡單的伺服器客戶 (C++))

1 編寫Service節點 這裡,我們將建立一個簡單的service節點("add_two_ints_server"),該節點將接收到兩個整型數字,並返回它們的和。 進入先前你在catkin workspace教程中所建立的beginner_tutorials包所在的目錄

qml中註冊使用C++物件以及在qml中實現窗體最大最小化

在main函式中相關程式碼如下: QApplicationapp(argc,argv); QDeclarativeViewview; //將app註冊到qml中,方便對主程式的退出,最大最小化等相關操作 view.rootContext()->setCont

ROS的學習(十六)用C++寫一個簡單的伺服器(service)客戶(client)

      我們將建立一個伺服器節點add_two_ints_server,它將會收到兩個整數,並且返回它們的和。切換目錄到之前建立的beginner_tutorials包下: cd ~/catkin_ws/src/beginner_tutorials      編輯sr

編寫測試簡單的伺服器客戶 (C++)(十一)

本教程介紹如何用 C++ 編寫伺服器 Service 和客戶端 Client 節點。 內容 編寫Service節點 程式碼 程式碼解釋 編寫Client節點 程式碼 程式碼解釋 編譯節點 編譯節點 編寫Service節點

ROS學習筆記7-編寫簡單的伺服器客戶 (C++)

1 前提在/catkin_ws/src/beginner_tutorials/srv 目錄下建立好AddTwoInts.srv 1 int64 a 2 int64 b 3 --- 4 int64 sum 2 編寫server節點[~/catkin_ws/src/

C++】大端的理解

我的理解: 記憶體是以位元組為單位的,一個位元組是8位,也就是2位的16進位制,所以首先將資料轉成16進位制,比如下面例子中的0x12345678,就表示了4個位元組的資料。這裡要注意一點,如果將資料改成0x10,那麼這個還是4個位元組的資料,主要是位元組空間是由int所決定的,因此就

POJ-3243-Clever Y-擴充套件Bsgs演算法-已知acpa^b=c(mod p)求b

【Description】 Little Y finds there is a very interesting formula in mathematics: XYmod&MediumSpace;Z=K X^Y mod\:Z=K XYmodZ=K

使用C API 實現C調Python python調C

Python調C python 調C語言主要是將C程式碼編譯成so檔案,通過python端的ctypes匯入C庫使用C函式,簡單使用如下 void TestLib::hello(int a) { printf("hello world"); } extern "C

C++ 將 string 數字連線的實現程式碼

實現程式碼 #include <iostream> #include <string> using namespace std; int main() { string str = "ditong"; cout << str + to_strin

C#用serialPortchart控制元件實現簡單波形繪製

先看最終的效果圖: 主要實現功能是將串列埠傳送過來的資料按波形顯示 注:本例是以串列埠除錯助手和虛擬串列埠VSPD軟體模擬串列埠傳送資料的,詳細說明見下文 說明: serialPort的ReadByte()方法用於從System.IO.Ports.SerialPort輸入

C語言中*&的區別-程式碼實現說明

*是指標運算子,可以表示一個變數是指標型別;也可以表示一個指標變數的所指向的儲存單元,可以獲取某個地址儲存的值。 &是取地址符號,既取得某一個變數的地址 int *p=&a;

VTP配置伺服器server客戶client客戶會學習伺服器的VLAN

這種標題,看到就方了,什麼是VTP,trunk、channel這些配置過相關的命令,但是我不理解啊,這樣還能搭小型區域網絡? 本來是要求用dns3、或者eve做的實驗的,因為這兩款模擬器可以模擬真機,然後抓包,天天抓包,天天抓包,果然是學網路了 但是.....!!! 由於我

C++利用反射簡單工廠模式實現業務模組解耦

1. 業務說明 為了便於說明,舉一個簡單的例子。假設現在有一個專案需要建立一個和銀行互動的平臺,目前只接入工商銀行,後續接入其他銀行,每個銀行的業務都有差異,報文格式可能也不一致。 這裡只列舉幾個簡要的流程,僅包括拼報文,傳送報文,接收報文,解析報文,其餘整體架構以及

【轉】Effective C#觀後感之提高UnityC#代碼質量的21條準則

們的 嚴格 知識 將不 實現接口 控制流程 effect 序列 狀態 轉自:http://blog.csdn.net/swj524152416/article/details/75418162 我們知道,在C++領域,作為進階閱讀材料,必看的書是《Effective C++

神奇的C語言這才是C語言大牛操作作為面試題怕是秒殺眾人

想想 自己 初始 fun 怎麽 指向 都是 計算 換行 當然下面列出來的幾點都是C的基礎用法,只不過是這些用法可能平時不會被註意。所以很多東西第一次看到的時候,可能會覺得很怪異,但是細細想想就能很好的理解,也就能更好的清楚C語言的一些特性。但是在具體的編碼過程當中,我還是希

C++檔案輸入輸出(C++學習筆記 1)

為了開啟一個檔案供輸入或輸出,標頭檔案需要包括 #include<iostream> 和#include<fstream> iostream庫除了支援終端輸入輸出,也支援檔案的輸入和輸出。 1. 開啟一個輸出檔案 必須宣告一個ofstream型別的物件,來

Java類載入器( CLassLoader ) 死磕8: 使用ASM類載入器實現AOP

【正文】Java類載入器(  CLassLoader ) 死磕8:  使用ASM,和類載入器實現AOP 本小節目錄 8.1. ASM位元組碼操作框架簡介 8.2. ASM和訪問者模式 8.3. 用於增強位元組碼的事務類 8.4 通過ASM訪問註解 8.5. 通過ASM注入AOP事務程式

看明星合影爭C學PPT中C位排版法

在娛樂圈裡,C位是大咖位,是對藝人實力的最好證明,藝人們自然會想著去力爭C位,正所謂“不想當將軍的兵不是好兵,不想站C位的明星不是好明星”。 那麼,C位是什麼意思? C位,網路流行語,即center,中心位置的意思,指藝人在宣傳海報中的中間突出位置。如果在團隊組合中,站這個位置的是團隊核心;

前端如何實現高效協作

一、前後端分離 二、儘量避免後端模板渲染 web渲染方式分為伺服器端渲染和客戶端渲染,推薦使用客戶端渲染,資料通過ajax方式互動 三、儘量避免大量線上除錯 做好本地介面模擬開發 四、規範的介面文件 格式簡潔、介面名、介面描述、介面地址、http方法、引數、響應資料等 五