TCP Socket не останавливает получение данных в программе C # - PullRequest
3 голосов
/ 03 марта 2012

Java-приложение для Android с телефона Android 2.2 отправляет строковые данные в программу C #.Программа C # получает данные и показывает их правильно только в первый раз .Тогда это не прекращает получать данные.Но поскольку данных нет, они отображаются как 0 как полученные данные, при отладке и не получении данных, которые Java-приложение отправляет во второй раз.

Сначала я подумал, что приложение Java отправляетданные постоянно.Но программа на C # получает данные, хотя приложение Java закрылось.

Полный исходный код программы на 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 Ответ

2 голосов
/ 03 марта 2012

Если вы получаете что-то неположительное, это означает «конец». ваша задача - проверить это условие и прекратить запрашивать данные (на самом деле, возможно, отключить сокет на вашем конце).

Верно, что он вернет неположительное значение, даже еслиВы называете это 700 раз.Так что ... не делай этого.Как только вы получите iRx <= 0, <strong>прекратите запрашивать данные .

В качестве дополнительного примечания ваш код декодирования не является надежным;не гарантируется, что UTF-8 представляет собой один символ на байт, поэтому небезопасно предполагать, что символы заполнены данными.Вы должны захватить возврат из GetChars и использовать его в строковом конструкторе, чтобы ограничить количество символов, которые вы просматриваете.Или проще: просто используйте Encoding.Utf8.GetString (...)

...