TCP套接字不会停止在C#程序中接收数据 [英] TCP Socket is not stopping receiving data in C# program

查看:79
本文介绍了TCP套接字不会停止在C#程序中接收数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

来自Android 2.2手机的Java Android App正在将字符串数据发送到C#程序.C#程序会接收数据并正确地首次显示.然后,它不会停止接收数据.但是由于没有数据,因此它在调试时并显示为 0 作为接收的数据,而不接收Java App第二次发送的数据.

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.

首先我想,可能是Java应用程序正在连续发送数据.但是,即使Java App已关闭,C#程序仍在接收数据.

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

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

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. :)

推荐答案

如果得到的结果不是肯定的,则表示结束".您的工作是检查此情况,并停止请求数据(实际上,可能在您的末端关闭了套接字).

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).

即使调用了700次,它也会返回非正数,这是正确的.所以...别那样一旦您gt iRx< = 0,停止要求数据.

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.

需要特别注意的是,您的解码代码不可靠;不能保证UTF-8每字节一个字符,因此,不安全地假设字符填充了数据是不安全的.您应该捕获GetChars的返回值,并在字符串构造函数中使用它来限制所查看的字符.或更简单:只需使用Encoding.Utf8.GetString(...)

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(...)

这篇关于TCP套接字不会停止在C#程序中接收数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆