アットウィキロゴ

Mono

.NET Framework互換の環境を実現するためのオープンソースソフトウェア群
マルチプラットホームを実現する。

動作環境

Linux
FreeBSD
UNIX
Mac OS X
Solaris
Windows
etc

予定

SeleneをクライアントにMonoをサーバーとして、MMOゲームサーバーっぽいものを作成。
MonoはLinuxで実行する(WindowsだとTCP接続数で怒られるため)(Biotは使わない方向で
sheevaplugで接続したかったりする

メモ

通信はByteの送受信行われるので
送信する場合は[構造体→byte]
受信する場合は[byte→構造体]へキャストしなければならない。
しかし、Cと違って簡単にはキャストできない。
アンマネージドは注意して使わないといけない

ネームスペース
using System.Runtime.InteropServices;

構造体宣言
public struct SUSL_STRUCT
{
	public int nHoge1;
	public int nHoge2;
};

共用体とBYTE固定配列
[StructLayout(LayoutKind.Explicit)]
unsafe public struct SUSL_NETWORK_UNION
{
// 固定のデータ(このサイズが共用される)
[FieldOffset(0)]  public fixed byte byData[64];

// イベントデータ
[FieldOffset(4)]  public int nEventType;
	
// 構造体(共有される)
[FieldOffset(8)]  public SUSL_STRUCT		sHoge1;
[FieldOffset(8)]  public SUSL_STRUCT		sHoge2;
};
// 宣言する(※ローカル変数として宣言すると[fixed]でエラーが吐かれます!)
SUSL_NETWORK_UNION sNetworkUnion;

BYTEから構造体に変換
unsafe
{
// 受信によりbyRecvにはbyteのデータが入る
受信(byRecv);
fixed (byte* pSrc = byRecv)
fixed (byte* pDest = sNetworkUnion.byData)
{
	*(SUSL_NETWORK_UNION*)pDest = *(SUSL_NETWORK_UNION*)pSrc ;
}
// sNetworkUnionにデータが入るので、後はご自由に
}


構造体からBYTEに変換
unsafe
{
// データを入れる
sNetworkUnion.nEventType = 1;
sNetworkUnion.nHoge1 = 1234;
sNetworkUnion.nHoge2 = 2222;

// 構造体のサイズを取得し、byteで領域を確保する
int size = sizeof(SUSL_NETWORK_UNION);
byte[] bySendData = new byte[size];
// 変換
fixed (byte* pSendDataPointer = bySendData)
{
	*(SUSL_NETWORK_UNION*)pSendDataPointer = sNetworkUnion;
}
// 構造体の内容を送る
送信(bySendData);
}


BYTEをUint16に変換
// オフセット
int nOffset = 0;

// イベント						
byte[] byEvent		= { pPacketRecvData.byPacket[nOffset], pPacketRecvData.byPacket[nOffset + 1] };
UInt16 nEvent		= BitConverter.ToUInt16(byEvent, 0);
nOffset += byEvent.Length;

// サイズ
byte[] bySize		= { pPacketRecvData.byPacket[nOffset], pPacketRecvData.byPacket[nOffset + 1] };
UInt16 nSize		= BitConverter.ToUInt16(bySize, 0);
nOffset += bySize.Length;


BYTEをString(utf-16)に変換
// エンコーディング
Encoding m_ecConvertCode = Encoding.GetEncoding("utf-16");
// オフセット
int nOffset = 0;
 
// 名前
int nUserNameSize = (int)CUSL_NetworkManager.EUSL_USER.MAX_NAME_BYTE;
string []strUserName	= m_ecConvertCode.GetString(pPacketRecvData.byPacket, nOffset, nUserNameSize).Split('\0');
nOffset += nUserNameSize;

// パスワード
int nUserPasswordSize = (int)CUSL_NetworkManager.EUSL_USER.MAX_PASSWORD_BYTE;
string []strUserPass	= m_ecConvertCode.GetString(pPacketRecvData.byPacket, nOffset, nUserPasswordSize).Split('\0');			
nOffset += nUserPasswordSize;


String(utf-16)をBYTE固定配列に変換
byte []byName = m_ecConvertCode.GetBytes("名前");
for(int i = 0; i < byName.Length; i ++)
{
fixed (byte* p = m_sChatDataUnion.sData.szUserName)
{
	p[i] = byName[i];
}
}
byte []byString = m_ecConvertCode.GetBytes("あいうえお");
for(int i = 0; i < byString.Length; i ++)
{
fixed (byte* p = m_sChatDataUnion.sData.szString)
{
	p[i] = byString[i];
}
}
最終更新:2009年10月02日 03:12
ツールボックス

下から選んでください:

新しいページを作成する
ヘルプ / FAQ もご覧ください。