このすべての背後にある物語
一度に複数の RPG で使用できる、オープン ソースの RPG インベントリ サーバーを作成しようとしています。後でそのためのゲームを作成します。私の最初のバージョンは、多くのセキュリティや暗号化をサポートしていません。でもしっかりスタートしたい。
問題
1 つの接続、ドロップイン、ドロップアウトを受け入れます。しかし、スレッド化の私の実装は、1 つの接続しか受け入れないようです。これを適切に行う方法についてのガイドラインを教えてくれる人はいますか? 読みやすくするために、提供するコードにコメントを付けました。
セットアップ SP1 を有効にした Visual Studio 2010 を使用しています。ホーム ネットワーク内でのみ試したので、IP 転送は必要ありません。両方の PC を別々に受け入れます。
助けてくれた人たちに感謝します。あなたが助けて最終結果にクレジットされたい場合は、私に知らせてください. 誰かが一般的なコメントを持っているなら、私はそれらを聞きたいです;)
編集: NewIPEP() メソッドと関係があります。
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
namespace TCPServer1
{
class ServerV1
{
static int maxthreads = 4;
static bool[] threadavailable = new bool[maxthreads];
static Thread[] listenThread = new Thread[maxthreads];
static IPEndPoint[] ipep = new IPEndPoint[maxthreads];
static bool[] threadconnected = new bool[maxthreads];
static Socket[] newsock = new Socket[maxthreads];
static Socket[] client = new Socket[maxthreads];
static ItemListClassV1 parent;
static Login loginin;
static ProtoColV1[] protocol = new ProtoColV1[maxthreads];
/// <summary>
/// initialises variables and starts a first thread.
/// </summary>
/// <param name="args"></param>
public ServerV1(ItemListClassV1 parentid, Login login)
{
for (int i = 0; i < maxthreads; i++)
{
threadavailable[i] = true;
}
parent = parentid;
loginin = login;
StartThread();
}
/// <summary>
/// should be split but handles the servershit look further for seperate "method" comments
/// </summary>
static void Server()
{
int recv = 0;
byte[] data = new byte[1024];
//looks for incoming connections
ipep[Convert.ToInt32(System.Threading.Thread.CurrentThread.Name)] = NewIPEP();
newsock[Convert.ToInt32(System.Threading.Thread.CurrentThread.Name)] = new
Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
newsock[Convert.ToInt32(System.Threading.Thread.CurrentThread.Name)].Bind(ipep[Convert.ToInt32(System.Threading.Thread.CurrentThread.Name)]);
newsock[Convert.ToInt32(System.Threading.Thread.CurrentThread.Name)].Listen(10);
Console.WriteLine("Waiting for a client...");
client[Convert.ToInt32(System.Threading.Thread.CurrentThread.Name)] = newsock[Convert.ToInt32(System.Threading.Thread.CurrentThread.Name)].Accept();
//if connected
IPEndPoint clientep =
(IPEndPoint)client[Convert.ToInt32(System.Threading.Thread.CurrentThread.Name)].RemoteEndPoint;
Console.WriteLine("Connected with {0} at port {1}",
clientep.Address, clientep.Port);
//if connection start a new thread
StartThread();
//send welcome message to client
string welcome = "Welcome to my test server";
data = Encoding.ASCII.GetBytes(welcome);
client[Convert.ToInt32(System.Threading.Thread.CurrentThread.Name)].Send(data, data.Length,
SocketFlags.None);
while (true)//this looks for incoming data and sends reply.
{
try
{
data = new byte[1024];
recv = client[Convert.ToInt32(System.Threading.Thread.CurrentThread.Name)].Receive(data);
}
catch (SocketException e)
{
if (e != null)
break;
}
if (client[Convert.ToInt32(System.Threading.Thread.CurrentThread.Name)].Connected != true)//when not connected break the loop
{
break;
}
////EXECUTES moet wer trug
//byte[][] packets = protocol[Convert.ToInt32(System.Threading.Thread.CurrentThread.Name)].Execute(data,recv);//EXECUTES THE DATA EXTERNALLY
byte[][] packets = new byte[1][];
packets[0] = data;
for (int i = 0; i < packets.Length; i++)//stuurt vervolgens alle pakketjes
{
client[Convert.ToInt32(System.Threading.Thread.CurrentThread.Name)].Send(packets[i], packets[i].Length,
SocketFlags.None);
}
}
//when not connected this continues
Console.WriteLine("Disconnected from {0}",
clientep.Address);
//close socket
client[Convert.ToInt32(System.Threading.Thread.CurrentThread.Name)].Close();
newsock[Convert.ToInt32(System.Threading.Thread.CurrentThread.Name)].Close();
bool full = true;
//if the server was full now a slot opened
for (int l = 0; l < maxthreads; l++)
{
if (threadavailable[l])
{
full = false;
}
if (!threadavailable[l] && !threadconnected[l])
{
full = false;
}
}
//closes thread, deletes information
threadavailable[Convert.ToInt32(System.Threading.Thread.CurrentThread.Name)] = true;
ipep[Convert.ToInt32(System.Threading.Thread.CurrentThread.Name)] = null;
protocol[Convert.ToInt32(System.Threading.Thread.CurrentThread.Name)] = null;
if (full)
{
StartThread();
}
//stops thread
listenThread[Convert.ToInt32(System.Threading.Thread.CurrentThread.Name)] = null;
System.Threading.Thread.CurrentThread.Abort();
}
/// <summary>
/// keeps searching for incoming connections and returns the found connection when found.
/// </summary>
/// <returns></returns>
static IPEndPoint NewIPEP()
{
IPEndPoint temp = null;
bool newconnection = false;
while (!newconnection)
{
temp = new IPEndPoint(IPAddress.Any, 9050);
for (int k = 0; k < maxthreads; k++)
{
if (!threadavailable[k] && ipep[k] != null && ipep[k].Address != null )
{
if (temp.Address == ipep[k].Address)
{
k = maxthreads;
break;
}
}
if (k == maxthreads - 1)
{
newconnection = true;
threadconnected[Convert.ToInt32(System.Threading.Thread.CurrentThread.Name)] = true;
}
}
}
return temp;
}
/// <summary>
/// finds the first unstarted thread and starts it
/// </summary>
static void StartThread()
{
for (int i = 0; i < maxthreads; i++)
{
if (threadavailable[i])
{
threadavailable[i] = false;
threadconnected[i] = false;
protocol[i] = new ProtoColV1(parent,loginin);
listenThread[i] = new Thread(Server);
listenThread[i].Name = Convert.ToString(i);
listenThread[i].Start();
break;
}
}
}
}
}