unity調用dll 實現非阻塞socket server 的tcp 網絡通信


dll端的代碼

#include "TcpSrv.h"
#pragma comment(lib,"ws2_32.lib")

static SOCKET sServer = INVALID_SOCKET;
static SOCKET sClient = INVALID_SOCKET;

int InitSrv(int ip, int port)
{
	WSADATA wsd;
	int retVal;
	//初始化Socket
	if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0)
	{
		printf("WSAStartup failed!\n");
		sServer = INVALID_SOCKET;
		return -1;
	}
	//創建用於監聽的Socket
	sServer = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (INVALID_SOCKET == sServer)
	{
		printf("socket failed!\n");
		WSACleanup();
		sServer = INVALID_SOCKET;
		return -2;
	}
	//設置Socket爲非阻塞模式
	int iMode = 1;
	retVal = ioctlsocket(sServer, FIONBIO, (u_long FAR*)&iMode);
	if (retVal == SOCKET_ERROR)
	{
		printf("ioctlsocket failed!\n");
		WSACleanup();
		sServer = INVALID_SOCKET;
		return -3;
	}
	//設置服務器Socket地址
	sockaddr_in addrServ;
	addrServ.sin_family = AF_INET;
	addrServ.sin_port = htons(9087);;				//htons(9990);
	addrServ.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); //htonl(INADDR_ANY);
	//綁定Socket Server到本地地址
	retVal = bind(sServer, (const struct sockaddr*)&addrServ, sizeof(sockaddr_in));
	if (retVal == SOCKET_ERROR)
	{
		printf("bind failed!\n");
		closesocket(sServer);
		WSACleanup();
		sServer = INVALID_SOCKET;
		return -4;
	}
	//監聽
	retVal = listen(sServer, 5);
	if (retVal == SOCKET_ERROR)
	{
		printf("listen failed!\n");
		closesocket(sServer);
		WSACleanup();
		sServer = INVALID_SOCKET;
		return -5;
	}
	return 0;
}


int RecTcpData(char *buf, int size)
{
	int retVal;
	if (sServer == INVALID_SOCKET)	return -1;
	if (sClient == INVALID_SOCKET)
	{
		sockaddr_in addrClient;
		int addrClientlen = sizeof(addrClient);
		sClient = accept(sServer, (sockaddr FAR*)&addrClient, &addrClientlen);
		return 0;
	}
	retVal = recv(sClient, buf, size, 0);
	if (SOCKET_ERROR == retVal)
	{
		int err = WSAGetLastError();
		if (err != WSAEWOULDBLOCK)
		{
			//其他錯誤 都重連
			//printf("recv failed!\n");
			//closesocket(sServer);
			closesocket(sClient);
			//WSACleanup();
			sClient = INVALID_SOCKET;
		}
		return 0;
	}
	if (retVal == 0)
	{
		//接收斷開
		closesocket(sClient);
		//WSACleanup();
		sClient = INVALID_SOCKET;
	}
	return retVal;
}

int SendTcpData(char *buf, int size)
{
	int retVal;
	if (sClient == INVALID_SOCKET)	return -1;
	retVal = send(sClient, buf, size, 0);
	if (retVal == 0)
	{
		closesocket(sClient);
		sClient == INVALID_SOCKET;
		return -1;
	}
	return 0;
}

unity端的調用代碼

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System.Runtime.InteropServices; 

public class H264Tex : MonoBehaviour {

    [DllImport("u3dtcpsrv")]
    private static extern int InitSrv(int ip, int port);

    [DllImport("u3dtcpsrv")]
    private static extern int RecTcpData(ref byte buf, int size);

    byte[] tcpData;

    void Start()
    {
        int test;
        tex = new Texture2D(1920, 1080);
        tcpData = new byte[8];
        test = InitSrv(0x0100007F, 0x7C23);
        Debug.Log("this is a test"+test.ToString());
    }
	// Update is called once per frame
	void Update () {
       int reccnt = RecTcpData(ref tcpData[0], 8);

       if (reccnt <0)
       {
           Debug.Log(tcpData.ToString());
       }
       else if (reccnt ==1)
       {
           Debug.Log(tcpData.ToString());
       }
       else if (reccnt == 2)
       {
           Debug.Log(tcpData.ToString());
       }
       else if (reccnt == 3)
       {
           Debug.Log(tcpData.ToString());
       }
       else if (reccnt == 4)
       {
           Debug.Log(tcpData.ToString());
       }
    }
    void OnDestroy()
    {
        StopRunning();
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章