首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > C# >

C# C/S 客户端与服务器端交户解决思路

2013-09-26 
C#C/S 客户端与服务器端交户服务器端代码:namespace Server{static class Program{/// summary/// 应用

C# C/S 客户端与服务器端交户
服务器端代码:

namespace Server
{
    
    static class Program
    {
        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        /// 
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            //Application.Run(new Form3());
            Application.Run(new ServerForm());
        }
    }
}


public void run()
        {
            ipIpep = new IPEndPoint(IPAddress.Any,6666);   //服务器从6666端口接收客户端的登陆请求
            receiveUdpClient = new UdpClient(ipIpep);
            sendUdpClient = new UdpClient();
            
            receiveState = new UdpState();
            receiveState.udpClient = receiveUdpClient;
            receiveState.ipEndPoint = ipIpep;

            sendState = new UdpState();
            sendState.udpClient = sendUdpClient;
            sendState.ipEndPoint = remoteIpep;   
            ReceiveMsg();       
         }    
            public void ReceiveMsg()
            {


                try
                {          //循环接受客户端发过来的请求并响应
                    while (true)
                    {
                        lock (this)
                        {
                            IAsyncResult iar = receiveUdpClient.BeginReceive(new AsyncCallback(ReceiveCallback),receiveState);
                            receiveDone.WaitOne();
                            Thread.Sleep(100);
                        }
                     }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.StackTrace);
                    MessageBox.Show(ex.Message);
                }   
            }
            private void ReceiveCallback(IAsyncResult iar)
            {
                UdpState receiveState = iar.AsyncState as UdpState;


                if (iar.IsCompleted)
                {
                    data = receiveState.udpClient.EndReceive(iar,ref receiveState.ipEndPoint);
                    int i = 0;
                    ///取出命令
                    for (i = 0; i < leng; i++)
                    {
                        if (Convert.ToInt32(data[i]) == 0)    //寻找请求中的有效字符的最终位置
                            break;
                    }
                    byte[] cmdbyte = new byte[i];
                    for (int k = 0; k < i; k++)
                    {
                        cmdbyte[k] = data[k];
                    }
                    commandStr = Encoding.ASCII.GetString(cmdbyte);
                    MessageBox.Show(commandStr,"kkk");
                    ///取出数据
                    buff = new byte[data.Length - leng];


                    for (int j = 0; j < data.Length - leng; j++)
                        buff[j] = data[leng + j];
                    memStream = new MemoryStream(buff);
                    memStream.Seek(0, SeekOrigin.Begin);
                    obj = formatter.Deserialize(memStream);
                    memStream.Close();
                    if (obj != null && obj is User)
                        user = (User)obj;
                    remoteIpep = new IPEndPoint(receiveState.ipEndPoint.Address, 8888);
                    handleMsg(commandStr);
                    receiveDone.Set();
                }
            }

            //处理消息
            private void handleMsg(String msg)
            {
                switch (msg)
                {
                    case "Login":
                        string sqlLogin = "SELECT * FROM tb_users where 用户名='" + user.Username + "' and 密码='" + user.Password + "'and 启用标志=1";


                        multipleDB.getcon();
                        SqlDataReader reader = multipleDB.getread(sqlLogin);
                        if(contactWithClient==null)
                        contactWithClient = new ContactWithClient();
                        if (reader.HasRows) //身份验证成功
                        {
                            ///将登陆日志插入用户日志中
                            string sqlLoginJournal = "INSERT INTO tb_journal(用户名,操作类型ID,操作时间,描述,审计状态) VALUES('" + user.Username + "'," + 1 + ",'" + DateTime.Now + "','登陆了用户客户端'," + 0 + ")";
                            multipleDB.getcon();
                            multipleDB.getcom(sqlLoginJournal);                          
                            contactWithClient.User = user;
                            Sthread = new Thread(new ThreadStart(contactWithClient.ReceiveMsg));
                            Sthread.Start();
                          


                            ///将用户的详细信息查出来,返回给客户端
                            string sqluser = "SELECT 姓名,部门名称 FROM tb_users,tb_department where 用户名='" + user.Username + "' AND tb_users.部门ID=tb_department.部门ID";
                            multipleDB.getcon();
                            DataTable dt = new DataTable();
                            dt = multipleDB.getdt(sqluser);
                            user.Name=dt.Rows[0][0].ToString();
                            user.Department=dt.Rows[0][1].ToString();
                            info = Encoding.ASCII.GetBytes("LoginSuccess");
                            byte[] cmd = new byte[20];
                            for (int i = 0; i < info.Length; i++)
                            {
                                cmd[i] = info[i];
                            }
                            memStream = new MemoryStream();


                            formatter.Serialize(memStream, user);
                            byte[] data = memStream.ToArray();                  //将User对象发送给客户端
                            memStream.Flush();
                            memStream.Close();
                            byte[] buffer = new byte[cmd.Length + data.Length];
                            Array.Copy(cmd, 0, buffer, 0, cmd.Length);
                            Array.Copy(data, 0, buffer, cmd.Length, data.Length);

                            contactWithClient.SendMsg(buffer, buffer.Length, remoteIpep);
                            contactWithClient.remoteEp(remoteIpep); 
                        }
                        else //身份验证失败
                        {
                            info = Encoding.ASCII.GetBytes("LoginFail");
                            contactWithClient.SendMsg(info, info.Length,remoteIpep);


                        }
                        reader.Close();
                        break;
                }
            }


客户端退出后,若服务器不退出,等上一段时间后红色代码就会出错,出错信息:由于系统缓存空间不足或列队已满,不能执行套接字上的操作
[解决办法]
引用:
客户端代码:
private void 登陆_Load(object sender, EventArgs e)
        {
            contactWithServer = new ContactWithServer(this);
            clientcontactserverThread = new Thread(new ThreadStart(contactWithServer.ReceiveMsg));
            clientcontactserverThread.Start();           
        }



public ContactWithServer(登陆 loginForm)
        {
            this.loginForm = loginForm;
            //this.user = user;
            localIpep = new IPEndPoint(IPAddress.Any, 8888);
            remoteIpep = new IPEndPoint(IPAddress.Parse(serverIP), 6666);//客户端把登陆请求发给服务器6666端口
            udpReceiveClient = new UdpClient(localIpep);
            udpSendClient = new UdpClient();



            udpSendState = new UdpState();
            udpSendState.ipEndPoint = remoteIpep;
            udpSendState.udpClient = udpSendClient;

            udpReceiveState = new UdpState();
            udpReceiveState.ipEndPoint = localIpep;
            udpReceiveState.udpClient = udpReceiveClient;
        }


要是客户端和服务器不指定端口的话,服务器能收到数据,但是客户端收不到。若是都指定的话,只能运行一个客户端,这个该怎么解决。。

首先你要搞清楚你使用的那个协议!如果是TCP/IP 协议的话必须指定端口因为是点对点的通讯,如果是UDP 就不需要指定客户端端口使用广播即可。看你的代码好像是前者!
[解决办法]
你的锁  lock 用的有问题你应该是锁住 一个请求的对象 但是你这里lock(this)不知道想干什么。
你可以使用队列 把接收的请求放在队列里面然后逐个处理!
[解决办法]
参考:http://www.cnblogs.com/zhili/archive/2012/08/25/TCP.html
[解决办法]
UDP 协议服务器的端口肯定要固定啊 要不然就惨了  客户端端口不固定 哪服务器就变成一般的客户端了 那就不存在服务器这一说了!UDP虽然是无链接的 但是服务器地址是固定的啊.
[解决办法]
LZ

你可以到CSDN 中下一个源码看看!

热点排行