.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