问题
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