当服务器在Chat Socket Winform Application中检索客户端时,无法接收数据

时间:2016-01-03 09:24:33

标签: c# winforms sockets

我在Windows窗体应用程序中实现了一个聊天套接字程序。我的客户端程序无法从服务器接收数据。我不确切地知道我的问题所以我无法描述更多细节。我是套接字编程的新手,而我的客户端程序很糟糕。我怎样才能改进这个程序?

Client.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net.Sockets;
using System.Net;
using System.Threading;


namespace ChatClient
{
    public partial class Form1 : Form
    {
        byte[] data = new byte[1024];
        string input;
        int port;
        TcpClient server;
        int recv;
        public event FormClosedEventHandler FormClosed;
        string stringData;
        public Form1()
        {
            InitializeComponent();
            Form_Load();
        }
        /// <summary>
        /// 
        /// </summary>
        public void Form_Load()
        {
            rtbContent.AppendText("Please Enter the port number of Server:\n");

        }
        /// <summary>
        /// Function connect to server with port number
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnConnect_Click(object sender, EventArgs e)
        {
            input = txtPort.Text;
            port = Int32.Parse(input);
            try
            {
                server = new TcpClient("127.0.0.1", port);
            }
            catch (SocketException)
            {
                rtbContent.AppendText("Unable to connect to server");
                return;
            }
            rtbContent.AppendText("Connected to Server...\n");
        }
        /// <summary>
        /// Function send data to server.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnSend_Click(object sender, EventArgs e)
        {
            NetworkStream ns = server.GetStream();
            StateObject state = new StateObject();
            state.workSocket = server.Client;
            server.Client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                  new AsyncCallback((new Form1()).OnReceive), state);
                input = rtbSend.Text;
                if (input == "exit")
                    return;
                ns.Write(Encoding.ASCII.GetBytes(input), 0, input.Length);
                ns.Flush();

                rtbContent.AppendText(rtbSend.Text);
                rtbSend.Text = "";

                receiveData(sender, e);
                ns.Close();
        }
        /// <summary>
        /// Event called when server send data for client.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void receiveData(object sender, EventArgs e)
        {
            NetworkStream ns = server.GetStream();
            StateObject state = new StateObject();
            server.Client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                  new AsyncCallback((new Form1()).OnReceive), state);
            data = new byte[1024];
            recv = ns.Read(data, 0, data.Length);
            stringData = Encoding.ASCII.GetString(data, 0, recv);
            rtbContent.AppendText(stringData);

        }
        /// <summary>
        /// Event called when Form close.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Form1_FormClosed(Object sender, FormClosedEventArgs e)
        {
            rtbContent.AppendText("Disconnecting from server...");
            server.Close();
            MessageBox.Show( "FormClosed Event");
        }
        /// <summary>
        /// Asynchronous Callback function which receives data from client
        /// </summary>
        /// <param name="ar"></param>
        public void OnReceive(IAsyncResult ar)
        {
            String content = String.Empty;

            // Retrieve the state object and the handler socket
            // from the asynchronous state object.
            StateObject state = (StateObject)ar.AsyncState;
            Socket handler = state.workSocket;
            int bytesRead;

            if (handler.Connected)
            {

                // Read data from the client socket. 
                try
                {
                    bytesRead = handler.EndReceive(ar);
                    if (bytesRead > 0)
                    {
                        // There  might be more data, so store the data received so far.
                        state.sb.Remove(0, state.sb.Length);
                        state.sb.Append(Encoding.ASCII.GetString(
                                         state.buffer, 0, bytesRead));

                        // Display Text in Rich Text Box
                        content = state.sb.ToString();
                        rtbContent.AppendText(content.ToString());

                        handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                            new AsyncCallback(OnReceive), state);

                    }
                }

                catch (SocketException socketException)
                {
                    //WSAECONNRESET, the other side closed impolitely
                    if (socketException.ErrorCode == 10054 || ((socketException.ErrorCode != 10004) && (socketException.ErrorCode != 10053)))
                    {
                        handler.Close();
                    }
                }

            // Eat up exception....
                catch (Exception exception)
                {
                    MessageBox.Show(exception.Message + "\n" + exception.StackTrace);

                }
            }
        }
    }
    /// <summary>
    /// Server receive state
    /// </summary>
    public class StateObject
    {
        // Client  socket.
        public Socket workSocket = null;
        // Size of receive buffer.
        public const int BufferSize = 1024;
        // Receive buffer.
        public byte[] buffer = new byte[BufferSize];
        // Received data string.
        public StringBuilder sb = new StringBuilder();
    }
}

Server.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net.Sockets;
using System.Net;
using System.Threading; 

namespace ChatServer
{
    public partial class ChatDialog : Form
    {
        private TcpClient client;
        private NetworkStream clientStream;
        public delegate void SetTextCallback(string s);
        private Form1 owner;

        public TcpClient connectedClient
        {
            get { return client; }
            set { client = value; }
        }

        #region Constructors
        public ChatDialog()
        {
            InitializeComponent();
        }
        /// <summary>
        /// Constructor which accepts Client TCP object
        /// </summary>
        /// <param name="parent"></param>
        /// <param name="tcpClient"></param>
        public ChatDialog(Form1 parent, TcpClient tcpClient)
        {
            InitializeComponent();

            this.owner = parent;
            // Get Stream Object
            connectedClient = tcpClient;
            clientStream = tcpClient.GetStream();

            // Create the state object.
            StateObject state = new StateObject();
            state.workSocket = connectedClient.Client;

            // Call Asynchronous Receive Function 
            connectedClient.Client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, 
                new AsyncCallback(OnReceive), state);

            //connectedClient.Client.BeginDisconnect(true, new AsyncCallBack(DisconnectCallBack),state);
            rtbChat.AppendText("Chat here");
        }
        #endregion

        /// <summary>
        /// This function is used to display data in Rick Text Box
        /// </summary>
        /// <param name="text"></param>
        private void SetText(string text)
        {
            // InvokeRequired required compares the thread ID of the
            // calling thread to the thread ID of the creating thread.
            // If these threads are different, it returns true.
            if (this.rtbChat.InvokeRequired)
            {
                SetTextCallback d = new SetTextCallback(SetText);
                this.Invoke(d, new object[] { text });
            }
            else
            {
                this.rtbChat.SelectionColor = Color.Blue;
                this.rtbChat.SelectedText = "\nFriend: " + text;
            }
        }

        #region Send/Receive Data From Sockets
        /// <summary>
        /// Function to Send Data to Client
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnSend_Click(object sender, EventArgs e)
        {
            byte[] bt;
            bt = Encoding.ASCII.GetBytes(txtMessage.Text);
            connectedClient.Client.Send(bt);

            rtbChat.SelectionColor = Color.IndianRed;
            rtbChat.SelectedText = "\nMe:    " + txtMessage.Text;
            txtMessage.Text = "";
        }

        /// <summary>
        /// Asynchronous Callback function which receives data from server
        /// </summary>
        /// <param name="ar"></param>
        private void OnReceive(IAsyncResult ar)
        {
            String content = String.Empty;

            // Retrieve the state object and the handler socket
            // form the asynchronous state object.
            StateObject state = (StateObject)ar.AsyncState;
            Socket handler = state.workSocket;
            int bytesRead;

            if (handler.Connected)
            {
                // Read data from the client socket.
                try
                {
                    bytesRead = handler.EndReceive(ar);
                    if (bytesRead > 0)
                    {
                        // There  might be more data, so store the data received so far.
                        state.sb.Remove(0, state.sb.Length);
                        state.sb.Append(Encoding.ASCII.GetString(
                                         state.buffer, 0, bytesRead));

                        // Display Text in Rich Text Box
                        content = state.sb.ToString();
                        SetText(content);

                        handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                            new AsyncCallback(OnReceive), state);
                    }
                }
                catch (SocketException socketException)
                {
                    //WSAECONNRESET, the other side closed impolitely
                    if (socketException.ErrorCode == 10054 || ((socketException.ErrorCode != 10004) && (socketException.ErrorCode != 10053)))
                    {
                        // Complete the disconnect request.
                        String remoteIP = ((IPEndPoint)handler.RemoteEndPoint).Address.ToString();
                        String remotePort = ((IPEndPoint)handler.RemoteEndPoint).Port.ToString();
                        this.owner.DisconnectClient(remoteIP, remotePort);

                        handler.Close();
                        handler = null;

                    }
                }
                // Eat up exception ... 
                catch (Exception exception)
                {
                    MessageBox.Show(exception.Message + "\n" + exception.StackTrace);
                }
            }
        }
        #endregion

        #region Commands
        /// <summary>
        /// Exit Event Handler. Exit menu item is selected, the dialog box is hidden from user.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Hide();
        }
        /// <summary>
        /// Event Called when Chat Dialog Box is Closed by user. Same as exit event of Menu.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ChatDialog_FormClosing(Object sender, FormClosingEventArgs e)
        {
            e.Cancel = true;
            this.Hide();

        }

        #endregion

        #region StateObject Class Definition
        /// <summary>
        /// StateObject Class to read data from Client
        /// </summary>
        public class StateObject
        {
            // Client  socket.
            public Socket workSocket = null;
            // Size of receive buffer.
            public const int BufferSize = 1024;
            // Receive buffer.
            public byte[] buffer = new byte[BufferSize];
            // Received data string.
            public StringBuilder sb = new StringBuilder();
        }

        #endregion
    }
}

Here is link my full code for testing

0 个答案:

没有答案