1

这一切背后的故事

我正在尝试编写一个开源 RPG 库存服务器,一次可用于超过 1 个 RPG,并且稍后会为它制作游戏。我的第一个版本不支持很多安全或加密。但我希望有一个坚实的开始。

问题

它确实接受一个连接,然后退出。但是我的线程实现似乎只接受一个连接。有人可以给我指导如何正确执行此操作吗?我已经评论了我将为您的阅读提供的代码。

设置 我使用启用了 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;

            }
        }
    }





}
}
4

2 回答 2

1

这不是答案,但我不知道如何添加评论......你检查过 Lidgren 吗?为什么要重新发明轮子? http://code.google.com/p/lidgren-network-gen3/

他有同样很好的例子来说明如何使用这个库。

祝你好运!

Linuxx

于 2013-05-26T01:47:18.803 回答
1

你只打了Socket client = newsock.Accept();一次电话,这就是为什么只接受一个客户。

于 2013-05-26T01:19:24.937 回答