TCP Socket is not stopping receiving data in C# program

▼魔方 西西 提交于 2020-03-19 06:24:09

问题


A Java Android App from an Android 2.2 phone, is sending string data to the C# program. The C# program receiving the data and showing it correctly for the first time only. Then it is not stopping receiving data. But since there is not data, it is showing as 0 as received data, while debugging and not receiving data which is sent second time by the Java App.

First I thought, may be Java app is sending data continuously. But C# program is receiving data even though the Java App has closed.

Full source code of C# program is at below:

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];
    }
}

I am getting crazy going through the source code over and over again. Please help me. :)


回答1:


If you get something non-positive, it means "end". It is your job to check this condition, and stop requesting data (in fact, probably shutdown the socket at your end).

It is correct that it will return non-positive even if you call it 700 times. So... Don't do that. As soon as you gt iRx <= 0, stop asking for data.

As an extra note, your decoding code is not robust; it is not guaranteed that UTF-8 is one char per byte, so it is not safe to assume that chars is filled with data. You should capture the return from GetChars, and use this in the string constructor to limit the characters you look at. Or simpler: just use Encoding.Utf8.GetString(...)



来源:https://stackoverflow.com/questions/9545527/tcp-socket-is-not-stopping-receiving-data-in-c-sharp-program

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!