c# - TCP 套接字不会停止在 C# 程序中接收数据

标签 c# sockets serversocket

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

我首先想到,可能是 Java 应用程序不断发送数据。但即使 Java 应用程序已关闭,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];
    }
}

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

最佳答案

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

调用700次还是返回非正数是对的。所以……不要那样做。一旦您 gt iRx <= 0,停止请求数据

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

关于c# - TCP 套接字不会停止在 C# 程序中接收数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9545527/

相关文章:

c# - 如何从我的方法外部访问 c sharp 中的对象?

Java套接字读取方法返回-1

Java客户端/服务器关闭后资源泄漏

c# - 如何在单独的线程中无休止地运行相同的方法

c# - 如何知道一个事件是否在那里被调用了三秒钟?

java - C# 中有 Integer 类吗?

python - 在 PyInstaller 中找不到导入的模块

java - 连接到服务器时客户端套接字超时

android - 当 InetAddress 改变时 ServerSocket 会发生什么?

Java serversocket控制同步问题