c#BeginReceive中并发TCP客户端的缓冲冲突

时间:2016-12-04 16:00:14

标签: c# tcp tcpclient asyncsocket

我写了一个TCP服务器(c#语言的异步套接字方法),可以从客户端获取用户名和密码,当一个客户端连接并提供用户名和密码时,一切都将正常工作,下一个用户可以存储他们的用户名和密码在一个列表中,但当一个客户端连接,然后第二个客户端同时连接时,第二个连接用户的密码取代了第一个客户端密码的正确位数;

the sequence events of environment

client1 connect;
client2 connect;

client1 enter username; (for example JOHN)
client2 enter username;(for example  JACK)
client2 enter password;(for example 123456)
client1 enter password;(for example abc)

in the list is see;
 list{
    [0]:
         username : JOHN
         password : 123
    [1] 
         username : JACK
         password : 123456
}

正如您在上面看到的那样,第一个连接的密码的大小正确但是第二个连接的客户端密码(之前输入密码) 我的代码是:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;
using System.Collections.Concurrent;

namespace MyTestServer
{
    class Program
    {
        public  byte[] _buffer;
        public byte[] _PASSBUFF;
        private static Socket _ServerSocket = new Socket (AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        private  List<SpecificClient> _ClientDirectory = new List<SpecificClient>();
        static void Main(string[] args)
        {
            Console.Title = "Server";
            Program SS = new Program();
            SS.SetupServer();
            //SetupServer();
            Console.ReadLine();
        }
        private  void SetupServer()
        {
                Console.WriteLine("Setting up server ...");
                _ServerSocket.Bind(new IPEndPoint(IPAddress.Any, 100));
                _ServerSocket.Listen(5);
                _ServerSocket.BeginAccept(new AsyncCallback(AcceptCallBack), _ServerSocket);    
        }
        private  void AcceptCallBack(IAsyncResult AR)
        {

            Socket socket = _ServerSocket.EndAccept(AR);
            _ServerSocket.BeginAccept(new AsyncCallback(AcceptCallBack), _ServerSocket);
            Console.WriteLine("Client Connected");
            string RequestForUsername = "Enter your username: ";
            byte[] RFU_byte = Encoding.ASCII.GetBytes(RequestForUsername);
            socket.BeginSend(RFU_byte, 0, RFU_byte.Length, SocketFlags.None, new AsyncCallback(onCompleteRequestForUsername), socket);

        }

        private  void onCompleteRequestForUsername(IAsyncResult AR)
        {
            Socket socket = (Socket)AR.AsyncState;
            socket.EndSend(AR);
            _buffer = new byte[1024];
            socket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, new AsyncCallback(onUsernameReceived), socket);

        }



        private  void onUsernameReceived(IAsyncResult AR)
        {
                Socket socket = (Socket)AR.AsyncState;
                int RcvFromClient = socket.EndReceive(AR);
                byte[] buffer = new byte[RcvFromClient];
                Array.Copy(_buffer, buffer, buffer.Length);
                string RcvUsername = Encoding.ASCII.GetString(buffer);
                SpecificClient NewUser = new SpecificClient();
                NewUser._username = RcvUsername;
                NewUser._UserSocket = socket;
                _ClientDirectory.Add(NewUser);

                buffer = new byte[1024];
                buffer = Encoding.ASCII.GetBytes("\r\nEnter your password: ");
                socket.BeginSend(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(onSendPropmtForPass), socket);



        }
        private void onSendPropmtForPass(IAsyncResult AR)
        {
            Socket socket = (Socket)AR.AsyncState;
            socket.EndSend(AR);
            _PASSBUFF = new byte[1024];
            socket.BeginReceive(_PASSBUFF, 0, _PASSBUFF.Length, SocketFlags.None, new AsyncCallback(onReceivePassword), socket);
        }

        private void onReceivePassword(IAsyncResult AR)
        {
            Socket socket = (Socket)AR.AsyncState;
            int ByteCountRcvPass = socket.EndReceive(AR);
            byte[] PassBuff = new byte[ByteCountRcvPass];
            Array.Copy(_PASSBUFF, PassBuff, PassBuff.Length);
            string RcvPassword = Encoding.ASCII.GetString(PassBuff);

            foreach ( SpecificClient Wanted in _ClientDirectory)
            {
                if (Wanted._UserSocket == socket)
                {
                    Wanted._password = RcvPassword;
                    break;
                }
            }

        }

    }
}

0 个答案:

没有答案
相关问题