TCP Socket没有停止在C#程序中接收数据

时间:2012-03-03 10:55:24

标签: c# sockets serversocket

来自Android 2.2手机的Java Android应用程序正在向C#程序发送字符串数据。 C#程序接收数据并首次正确显示 。然后它没有停止接收数据。但由于没有数据,它显示为0作为接收数据,同时调试并且不接收Java App第二次发送的数据。

首先我想,可能是Java app连续发送数据。但即使Java App已关闭,C#程序也在接收数据。

C#程序的完整源代码如下:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Windows.Forms;

namespace Network_IM
{
    public partial class Server : Form
    {
        public Socket listnerSocket;
        public Socket workerSocket;
        public AsyncCallback workerAsyncCallBack;

        //As a Client
        Socket clientSocket;

        public Server()
        {
            InitializeComponent();
            OnLoad();
            RegisterEvents();
        }

        private void RegisterEvents()
        {
            button1.Click += new EventHandler(button1_Click);
            txtInput.KeyDown += new KeyEventHandler(txtInput_KeyDown);
        }

        void txtInput_KeyDown(object sender, KeyEventArgs e)
        {
            if(e.KeyCode == Keys.Enter)
                button1_Click(null, null);
        }

        void button1_Click(object sender, EventArgs e)
        {
            try
            {
                clientSocket = new Socket(AddressFamily.InterNetwork, 

SocketType.Stream, ProtocolType.Tcp);
                clientSocket.Connect(IPAddress.Parse("192.168.1.5"), 8222);
                clientSocket.Send(Encoding.UTF8.GetBytes(txtInput.Text));
                clientSocket.Close();
                txtLog.Text += " | Me: " + txtInput.Text + " | ";
                txtInput.Clear();
                txtInput.Focus();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void OnLoad()
        {
            try
            {
                IPEndPoint ipLocal = new IPEndPoint(IPAddress.Any, 8221);
                listnerSocket = new Socket(AddressFamily.InterNetwork, 

SocketType.Stream, ProtocolType.Tcp);
                listnerSocket.Bind(ipLocal);
                listnerSocket.Listen(4);
                listnerSocket.BeginAccept(new AsyncCallback(OnClientConnect), 

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

        public void OnClientConnect(IAsyncResult asyn)
        {
            try
            {
                workerSocket = listnerSocket.EndAccept(asyn);
                WaitForData(workerSocket);
            }
            catch (ObjectDisposedException)
            {
                Debugger.Log(0, "1", "\n OnClientConnection: Socket has been 

closed\n");
            }
            catch (SocketException se)
            {
                MessageBox.Show(se.Message);
            }
        }

        private void WaitForData(Socket workerSoc)
        {
            try
            {
                if (workerAsyncCallBack == null)
                    workerAsyncCallBack = new AsyncCallback(OnDataReceived);
                CSocketPacket theSocPkt = new CSocketPacket();
                theSocPkt.thisSocket = workerSoc;
                workerSoc.BeginReceive(theSocPkt.dataBuffer, 0, 

theSocPkt.dataBuffer.Length, SocketFlags.None, workerAsyncCallBack, theSocPkt);
            }
            catch (SocketException se)
            {
                MessageBox.Show(se.Message);
            }
        }

        public void OnDataReceived(IAsyncResult asyn)
        {
            try
            {
                CSocketPacket theSockId = (CSocketPacket)asyn.AsyncState;
                int iRx = theSockId.thisSocket.EndReceive(asyn);
                char[] chars = new char[iRx + 1];
                Encoding.UTF8.GetDecoder().GetChars(theSockId.dataBuffer, 0, iRx, 

chars, 0);
                String szData = new String(chars);
                setTxtLogText(szData);
                WaitForData(workerSocket);
            }
            catch (ObjectDisposedException)
            {
                Debugger.Log(0, "1", "\nOnDataReceived: Socket has been 

closed\n");
            }
            catch (SocketException se)
            {
                MessageBox.Show(se.Message);
            }
        }

        delegate void setTxtLogTextDelegate(string newText);

        private void setTxtLogText(string newText)
        {
            try
            {
                if (txtLog.InvokeRequired)
                {
                    setTxtLogTextDelegate txtLogDelegate = new 

setTxtLogTextDelegate(setTxtLogText);
                    if (newText != "\0")
                        txtLog.Invoke(txtLogDelegate, new object[] { newText });
                }
                else
                    txtLog.Text += newText.Remove(1);
            }
            catch (Exception ex)
            { throw ex; }
        }
    }

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

我一遍又一遍地疯狂地浏览源代码。请帮我。 :)

1 个答案:

答案 0 :(得分:2)

如果你得到非正面的东西,就意味着“结束”。检查这种情况是你的工作,并停止请求数据(实际上,可能会关闭你的套接字)。

即使你召唤700次,它也会返回非正数。所以......不要那样做。只要您输出iRx< = 0,就会停止询问数据

另外请注意,您的解码代码不健全;不能保证UTF-8是每个字节一个字符,所以假设字符充满数据是不安全的。您应该从GetChars捕获返回值,并在字符串构造函数中使用它来限制您查看的字符。或者更简单:只使用Encoding.Utf8.GetString(...)