请问大神们:为什么c#socket通信时,同步的,客户端必须先收到服务器的应答,才开始发送数据,但是在服务器收到数据处理完后,反馈给客户端时为什么收不到了?
服务器代码:
namespace serverfile
{
public partial class Form1 : Form
{
string fileaddr = @"C:\Documents and Settings\Administrator\桌面\filetr\serverfile\recv.xml";
private Socket server = null;
private Socket client = null;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
//创建EndPoint
IPAddress ipAddress = IPAddress.Parse("127.0.0.1");
IPEndPoint endpoint = new IPEndPoint(ipAddress, 7000);
//创建socket
if (server == null)
{
server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
server.Bind(endpoint);
}
else
{
}
}
private void button2_Click(object sender, EventArgs e)
{
Control.CheckForIllegalCrossThreadCalls = false;
Thread TempThread = new Thread(new ThreadStart(this.StartReceive));
TempThread.Start();
}
private void StartReceive()
{
// IPEndPoint ipep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 7000);
// Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
// server.Bind(ipep);
while (true)
{
server.Listen(10);
client = server.Accept();
string str = "连接成功";
byte[] clientString = Encoding.Default.GetBytes(str);
client.Send(clientString);
EndPoint tempRemoteEP = client.RemoteEndPoint;
IPEndPoint tempRemoteIP = (IPEndPoint)tempRemoteEP;
//获取请求的远程计算机名称
string remoteIP = tempRemoteIP.Address.ToString();
label1.Text = "连接状态:已经连接!";
FileStream MyFileStream = new FileStream(fileaddr, FileMode.Create, FileAccess.Write);
byte[] data = new byte[2048];
int sent=0;
while (true)
{
sent=client.Receive(data);
if (sent == 0)
{
break;
}
else
{
// SendedCount++;
MyFileStream.Write(data, 0, sent);
}
}
MyFileStream.Close();
xmlread(client );
client.Close();
}
}
public void xmlread(Socket s)
{
XmlDocument doc = new XmlDocument();
// doc.Load(@"D:\Csharp\xmlread\CKECKINFO_Device_id_1.xml"); //加载Xml文件
doc.Load(fileaddr); //加载Xml文件
// 得到根节点bookstore
XmlNode xn = doc.SelectSingleNode("info");
// 得到根节点的所有子节点
XmlNodeList xnl = xn.ChildNodes;
string str = "";
foreach (XmlNode xn1 in xnl)
{
// 将节点转换为元素,便于得到节点的属性值
XmlElement xe = (XmlElement)xn1;
str = str + "user_id" + xe.GetAttribute("user_id").ToString();
// 得到Book节点的所有子节点
XmlNodeList xnl0 = xe.ChildNodes;
str = str + ";" + xnl0.Item(0).InnerText;
str = str + ";" + xnl0.Item(1).InnerText;
str = str + ";" + xnl0.Item(2).InnerText;
str = str + ";" + xnl0.Item(3).InnerText;
str = str + ";" + xnl0.Item(4).InnerText;
}
MessageBox.Show(str);
string str1 = "接收成功";
byte[] clientString1 = Encoding.Default.GetBytes(str1);
s.Send(clientString1);
File.Delete(fileaddr);
}
}
}
客户端代码:
namespace clientfile
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Thread TempThread = new Thread(new ThreadStart(this.StartSend));
TempThread.Start();
}
private void StartSend()
{
//FileInfo EzoneFile = new FileInfo(this.textBox1.Text);
string path = @"C:\Documents and Settings\Administrator\桌面\filetr\clientfile\CKECKINFO_Device_id_1.xml";
FileInfo EzoneFile = new FileInfo(path);
FileStream EzoneStream = EzoneFile.OpenRead();
int PacketSize = 2048;
int PacketCount = (int)(EzoneStream.Length / ((long)PacketSize));
int LastDataPacket = (int)(EzoneStream.Length - ((long)(PacketSize * PacketCount)));
IPEndPoint ipep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 7000);
Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
client.Connect(ipep);
byte[] data = new byte[PacketSize];
for (int i = 0; i < PacketCount; i++)
{
EzoneStream.Read(data, 0, data.Length);
TransferFiles.SendVarData(client, data);
}
if (LastDataPacket != 0)
{
data = new byte[LastDataPacket];
EzoneStream.Read(data, 0, data.Length);
TransferFiles.SendVarData(client, data);
// MessageBox.Show("client,data.length" + Convert.ToString(data.Length));
}
EzoneStream.Close();
Receive(client );
client.Close();
}
public void Receive(Socket s)
{
byte[] res = new byte[100];
s.Receive(res);
MessageBox.Show(Encoding.Default.GetString(res));
}
}
class TransferFiles
{
public TransferFiles()
{
}
public static int SendVarData(Socket s, byte[] data) // return integer indicate how many data sent.
{
int total = 0;
int size = data.Length;
int dataleft = size;
int sent;
while (total < size)
{
sent = s.Send(data, total, dataleft, SocketFlags.None);
total += sent;
dataleft -= sent;
}
return total;
}
Server的StartReceive里面的处理有误。
你在while循环**后**发送反馈,就是那个xmlread(client )。
但是,你的while循环只会在客户关闭socket连接的时候才退出,因此客户不能接收到你的反馈。
具体来说,while循环里面,你判断send==0的情况下退出循环(注:这里的send是错字,英文应该用received)。
但是根据MSDN参考,send==0意味着客户关闭连接。