通过套接字接收数据

时间:2015-10-22 09:48:13

标签: c#

我是C#的新手,我在从服务器发送数据并将其接收到客户端时遇到问题。 我不明白为什么我没有收到客户的数据。这是我的代码:

客户端:

public partial class Client : Form
{
    #region Declarations

    private byte[] dataBuffer = new byte[10];
    private IAsyncResult result;
    private AsyncCallback pfnCallback;
    private Socket clientSocket;

    #endregion

    public Client()
    {
        InitializeComponent();

        tbIP.Text = GetIP();
    }

    [STAThread]
    public static void Main(string[] args)
    {
        Application.Run(new Client());
    }

    private void btnConnectToServer_Click(object sender, EventArgs e)
    {
        if (tbIP.Text == "" || tbPort.Text == "")
        {
            MessageBox.Show("IP Address and Port Number are requierd to connect to the Server\n");
            return;
        }
        try
        {
            UpdateControls(false);

            clientSocket = new Socket(AddressFamily.InterNetwork,
                                      SocketType.Stream,
                                      ProtocolType.Tcp);

            IPAddress ip = IPAddress.Parse(tbIP.Text);
            int iPortNo = Convert.ToInt32(tbPort.Text);

            IPEndPoint ipEnd = new IPEndPoint(ip, iPortNo);

            clientSocket.Connect(ipEnd);
            if (clientSocket.Connected)
            {
                UpdateControls(true);
                WaitForData(clientSocket);
            }
        }
        catch (SocketException se)
        {
            string str;
            str = "\nConnection failed, is the server running?\n" + se.Message;
            MessageBox.Show(str);
            UpdateControls(false);
        }
    }

    public class SocketPacket
    {
        public Socket thisSocket;
        public byte[] dataBuffer = new byte[1];
    }

    public void WaitForData(Socket soc)
    {
        try
        {
            if (pfnCallback == null)
            {
                pfnCallback = new AsyncCallback(OnDataRecived);
            }
            SocketPacket theSocPkt = new SocketPacket();
            theSocPkt.thisSocket = soc;

            soc.BeginReceive(theSocPkt.dataBuffer, 0,
                                   theSocPkt.dataBuffer.Length,
                                   SocketFlags.None,
                                   pfnCallback,
                                   theSocPkt);
        }
        catch (SocketException se)
        {
            MessageBox.Show(se.Message);
        }
    }

    public void OnDataRecived(IAsyncResult asyn)
    {
        try
        {
            SocketPacket socketData = (SocketPacket)asyn.AsyncState ;

            int iRx  = 0;
            iRx = socketData.thisSocket.EndReceive (asyn);
            char[] chars = new char[iRx +  1];
            System.Text.Decoder d = System.Text.Encoding.UTF8.GetDecoder();
            int charLen = d.GetChars(socketData.dataBuffer, 
                                     0, iRx, chars, 0);
            System.String szData = new System.String(chars);
            this.BeginInvoke(new MethodInvoker(delegate()
            {
                this.rtbUpdate.Text += szData;
            }));
            WaitForData(socketData.thisSocket);
        }
        catch(ObjectDisposedException)
        {
            System.Diagnostics.Debugger.Log(0,"1","\nOnDataReceived: Socket has been closed\n");
        }
        catch(SocketException se)
        {
            MessageBox.Show(se.Message);
        }
    }

    private void btnDisconectFromServer_Click(object sender, EventArgs e)
    {
        if (clientSocket != null)
        {
            clientSocket.Close();
            clientSocket = null;
            UpdateControls(false);
        }
    }

    private void btnClose_Click(object sender, EventArgs e)
    {
        if (clientSocket != null)
        {
            clientSocket.Close();
            clientSocket = null;
        }
        Close();
    }

    private void UpdateControls(bool connected)
    {
        btnConnectToServer.Enabled = !connected;
        btnDisconectFromServer.Enabled = connected;
        string connectStatus = connected ? "Connected" : "Not Connected";
        tbConnection.Text = connectStatus;
    }

    String GetIP()
    {
        String strHostName = Dns.GetHostName();

        IPHostEntry iphostentry = Dns.GetHostByName(strHostName);

        String IPStr = "";
        foreach (IPAddress ipaddress in iphostentry.AddressList)
        {
            IPStr = ipaddress.ToString();
            return IPStr;
        }
        return IPStr;
    }
}

服务器:

public partial class Server : Form
{
    #region Declarations

    const int MAX_CLIENTS = 10;

    private AsyncCallback pfnWorkerCallback;
    private Socket mainSocket;
    private Socket[] workerSocket = new Socket[10];
    delegate void SetTextCallback(string text);
    private Thread client = null;
    private int clientCount = 0;

    public List<StudentData> studetsData = new List<StudentData>();
    public BindingSource source = new BindingSource();

    #endregion

    public Server()
    {
        InitializeComponent();

        dgvStudent.AutoGenerateColumns = false;

        studentName.DataPropertyName = "Name";
        studentAge.DataPropertyName = "Age";

        studetsData.Add(new StudentData("Борислав Петровски", 20));
        studetsData.Add(new StudentData("Светослав Кадиев", 34));

        source.DataSource = studetsData;
        dgvStudent.DataSource = source;

        tbIP.Text = GetIP();
    }

    [STAThread]
    public static void Main(string[] args)
    {
        Application.Run(new Server());
    }

    private void btnStartListening_Click(object sender, EventArgs e)
    {
        try
        {
            if (tbPort.Text == "")
            {
                MessageBox.Show("Please enter Port Number");
                return;
            }
            string portStr = tbPort.Text;
            int port = Convert.ToInt32(portStr);

            mainSocket = new Socket(AddressFamily.InterNetwork,
                                    SocketType.Stream,
                                    ProtocolType.Tcp);
            IPEndPoint ipLocal = new IPEndPoint(IPAddress.Any, port);

            mainSocket.Bind(ipLocal);

            mainSocket.Listen(4);

            mainSocket.BeginAccept(new AsyncCallback(OnClientConnect), null);

            UpdateControls(true);
        }
        catch (SocketException se)
        {
            MessageBox.Show(se.Message);
        }
    }

    private void UpdateControls(bool listening)
    {
        btnStartListening.Enabled = !listening;
        btnStopListening.Enabled = listening;
    }

    public void OnClientConnect(IAsyncResult asyn)
    {
        try
        {
            workerSocket[clientCount] = mainSocket.EndAccept(asyn);

            WaitForData(workerSocket[clientCount]);

            ++clientCount;

            this.client = new Thread(new ThreadStart(this.ThreadProcSafe));
            client.Start();

            mainSocket.BeginAccept(new AsyncCallback(OnClientConnect), null);
        }
        catch (ObjectDisposedException)
        {
            System.Diagnostics.Debugger.Log(0, "1", "\n OnClientConnection: Socket has benn closed\n");
        }
        catch (SocketException se)
        {
            MessageBox.Show(se.Message);
        }
    }

    public void WaitForData(Socket soc)
    {
        try
        {
            if (pfnWorkerCallback == null)
            {
                pfnWorkerCallback = new AsyncCallback(OnDataRecived);
            }
            SocketPacket theSocPkt = new SocketPacket();
            theSocPkt.currentSocket = soc;

            soc.BeginReceive(  theSocPkt.dataBuffer, 0, 
                               theSocPkt.dataBuffer.Length,
                               SocketFlags.None,
                               pfnWorkerCallback,
                               theSocPkt);
        }
        catch(SocketException se)
        {
            MessageBox.Show (se.Message);
        }
    }

    public void OnDataRecived(IAsyncResult asyn)
    {

    }

    public class SocketPacket
    {
        public Socket currentSocket;
        public byte[] dataBuffer = new byte[1];
    }

    private void btnStopListening_Click(object sender, EventArgs e)
    {
        CloseSockets();
        UpdateControls(false);
    }

    private void btnSendData_Click(object sender, EventArgs e)
    {
        try
        {
            object objData = SerializeStudent(dgvStudent.CurrentRow.DataBoundItem as StudentData);
            rtbUpdate.Text += "\n /////////// \n" + objData.ToString();
            byte[] bytesData = Encoding.UTF8.GetBytes(objData.ToString());
            if (mainSocket != null)
            {
                mainSocket.Send(bytesData);
            }
        }
        catch (SocketException se)
        {
            MessageBox.Show(se.Message);
        }
    }

    private string SerializeStudent(StudentData studentData)
    {
        StreamWriter streamWriter = null;
        XmlSerializer xmlSerializer;
        string buffer;
        try
        {
            xmlSerializer = new XmlSerializer(typeof(StudentData));
            MemoryStream memoryStream = new MemoryStream();
            streamWriter = new StreamWriter(memoryStream);
            xmlSerializer.Serialize(streamWriter, studentData);
            buffer = Encoding.UTF8.GetString(memoryStream.GetBuffer());
        }
        catch (Exception ex)
        {
            throw ex;
        }
        finally
        {
            if (streamWriter != null)
            {
                streamWriter.Close();
            }
        }
        return buffer;
    }

    private void btnClose_Click(object sender, EventArgs e)
    {
        CloseSockets();
        Close();
    }

    public string GetIP()
    {
        string strHostName = Dns.GetHostName();

        IPHostEntry iphostentry = Dns.GetHostByName(strHostName);

        string IPStr = "";
        foreach (IPAddress ipaddress in iphostentry.AddressList)
        {
            IPStr = ipaddress.ToString();
            return IPStr;
        }
        return IPStr;
    }

    public void CloseSockets()
    {
        if (mainSocket != null)
        {
            mainSocket.Close();
        }
        for (int i = 0; i < clientCount; i++)
        {
            if (workerSocket[i] != null)
            {
                workerSocket[i].Close();
                workerSocket[i] = null;
            }
        }
    }

    private void ThreadProcSafe()
    {
        this.SetText("");
    }

    private void SetText(string text)
    {
        text = string.Format("Client # {0} connected", clientCount);

        if (this.tbMessage.InvokeRequired)
        {

            //this.tbMessage.Text = text;
            SetTextCallback d = new SetTextCallback(SetText);
            this.Invoke(d, new object[] 
           {
               text 
           });
        }
        else
        {
            this.tbMessage.Text = text;
        }
    }
}

1 个答案:

答案 0 :(得分:0)

你设法避免了初学者的许多常见错误,但还有一些错误。

尽管如此,这不是代码审查,所以让我们专注于最直接的代码:您永远不会向任何客户发送任何数据!

您必须在通过相应的mainSocket.Send来电收到的每个客户端套接字上发出单独的Send,而不是按EndAccept发送。