日期:2014-05-18  浏览次数:20935 次

关于客户端与服务器通信问题(多线程)
现就客户端和服务器通信进行讨论:
进行测试的时候客户端LOGIN,服务器端没反应。跟踪调试两个程序之后,发现len = Stream.Read(buff,0,buff.Length);好像值是空的。到网上查,网友说是线程在程序结束时已经被关闭了!所以服务器的OK命令根本传不到客户端进行处理,也就是说流通道根本没有数据?而且调试程序的时候有提示由于以前的函数求值超时,函数求值被禁用。必须继续执行才能重新启用函数求值。
求救!!!!!!
还有一点客户端和服务端能在同一台机器上面测试吗?
服务器主要代码如下:
C# code

        private void btnSocketStart_Click(object sender, EventArgs e)
        {
            int port = getValidPort(tbSocketPort.Text);
            if (port < 0)
            {
                return;
            }
            string ip = this.getIPAddress();
            try
            {
                IPAddress ipAdd = IPAddress.Parse(ip);

                //创建服务器套接字
                listener = new TcpListener(ipAdd, port);

                //开始监听服务器端口
                listener.Start();

                this.rbSocketMsg.AppendText("Socket服务器已经启动,正在监听" + ip + "端口号" + this.tbSocketPort.Text + "\n");

                //启动一个新的线程,执行方法this.StartSocketListen
                //以便在一个独立的进程中执行确认与客户端Socket连接的操作
                ClientSeverForm.SocketServiceFlag = true;
                Thread thread = new Thread(new ThreadStart(this.StartSocketListen));

                thread.Start();
                this.btnSocketStart.Enabled = false;
                this.btnSocketStop.Enabled = true;
            }
            catch (Exception ex)//?????
            {
                this.rbSocketMsg.AppendText(ex.Message.ToString() + "\n");
            }
        }


        //在新的线程中的操作,它主要用于当接收到一个客户端请求时,确认与客户端的链接
        //并且立刻启动一个新的线程来处理和该客户端的信息交互
        private void StartSocketListen()
        {
            while (ClientSeverForm.SocketServiceFlag)
            {
                try
                {
                    //当接收到一个客户端请求时,确认与客户端的链接
                    if (listener.Pending())
                    {
                        Socket socket = listener.AcceptSocket();
                        if (clients.Count >= MAXNUM)
                        {
                            this.rbSocketMsg.AppendText("已经到达了最大连接数:" + MAXNUM + ",拒绝新的连接\n");
                            socket.Close();
                        }
                        else
                        { 
                            //启动一个新的线程
                            //执行方法this.ServiceClient,处理用户相应的请求
                            Client client = new Client(this, socket);
                            Thread clientService = new Thread(new ThreadStart(client.ServiceClient));
                            clientService.Start();
                        }
                    }
                    Thread.Sleep(200);
                }
                catch (Exception ex)
                {
                    this.rbSocketMsg.AppendText(ex.Message.ToString() + "\n");
                }
            }
        }



其中服务器端还包含了Client类,它封装了客户端的信息和连接,每有一个客户进入聊天室,就创建一个Client对象,用于保存该用户的信息并接收用户的数据和发送信息到客户端,该类主要代码如下
C# code

using System;
using System.Collections.Generic;
using System.Text;

//以下为程序引用到的库文件
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Collections;

namespace chatserver
{
    class Client
    {
        private string name;
        private Socket currentSocket = null;
        private string ipAddress;
        private ClientSeverForm server;

        //保存当前连接的状态
        //closed -->connected ->>closed
        private string state = "CLOSED";

        public Client(ClientSeverForm server, Socket clientSocket)
        {
            this.server = server;
            this.currentSocket = clientSocket;
            ipAddress = getRemoteIpAddress();
        }


        private void SendToCli