大概需求是客户端发送一个xml文件名给服务器,服务器返回xml文件。这一步没问题。
后面客户端需要解析xml文件,根据解析出的文件名,去服务器获取指定文件。现在问题是第一次服务器发送xml文件之后就侦听不到客户端后面的请求了
服务端代码:
#region 窗体加载
private void Form1_Load(object sender, EventArgs e)
{
Socket socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//Socket设置、IPv4、Stream类型套接字、TCP协议
IPAddress ip = IPAddress.Any;//获取本机IP
IPEndPoint point = new IPEndPoint(ip, 18002);//设置IP和端口
socketWatch.Bind(point);//绑定端口
memoEdit1.Text = "开始侦听...";
socketWatch.Listen(100);//最大连接数
Thread th = new Thread(SendFileFuncssss);//创建新线程
th.Start(socketWatch);//启动线程
th.IsBackground = true;//设置后台运行线程
}
#endregion
#region 根据客户端传输文件名发送指定文件
public void SendFileFuncssss(object obj)
{
Socket socket = obj as Socket;
while (true)
{
Socket socketServices = socket.Accept();
byte[] buffer = new byte[1024];
int num = socketServices.Receive(buffer);//接收到字节数
string str = Encoding.UTF8.GetString(buffer, 1, num - 1);//接收到字符串
if (buffer[0] == 0)//表示接收到的是消息数据
{
TxtAddContent(socketServices.RemoteEndPoint + "连接成功");
string FileName = str;
if (FileName.Equals("AutoUpdater.xml"))//获取xml配置文件
{
//发送XML文件到客户端
using (FileStream fs = new FileStream(AppDomain.CurrentDomain.BaseDirectory + FileName, FileMode.Open))
{
byte[] arrFile = new byte[1024 * 1024 * 5];
int length = fs.Read(arrFile, 0, arrFile.Length);
byte[] arrFileSend = new byte[length + 1];
arrFileSend[0] = 1; // 用来表示发送的是xml文件数据
Buffer.BlockCopy(arrFile, 0, arrFileSend, 1, length);
socketServices.Send(arrFileSend);// 发送数据到客户端
}
}
if (!FileName.Equals("AutoUpdater.xml"))
{
//发送更新文件到客户端
using (FileStream fs = new FileStream(AppDomain.CurrentDomain.BaseDirectory + "\\FileFolder\\" + FileName, FileMode.Open))
{
byte[] arrFile = new byte[1024 * 1024 * 50];
int length = fs.Read(arrFile, 0, arrFile.Length);//获取文件长度
byte[] arrFileSend = new byte[length + 1];
arrFileSend[0] = 1; // 用来表示发送的是xml文件数据
Buffer.BlockCopy(arrFile, 0, arrFileSend, 1, length);
socketServices.Send(arrFileSend);// 发送数据到服务端
}
}
}
}
}
#endregion
客户端代码:
Socket socketClient = obj as Socket;
socketClient.Connect(ipEndPoint);
#region 修改本地文件名称
string Oldpath = AppDomain.CurrentDomain.BaseDirectory + "AutoUpdater.xml";//修改前名称
string Newpath = AppDomain.CurrentDomain.BaseDirectory + "AutoUpdater_Back.xml";//修改后名称
if (File.Exists(Oldpath))
{
File.Delete(Newpath);
File.Move(Oldpath, Newpath);//更改文件名
}
#endregion
if (socketClient.Connected)
{
try
{
TxtReceiveAddContent("连接成功");
//发送链接成功提示
byte[] arrMsg = Encoding.UTF8.GetBytes("AutoUpdater.xml");
byte[] arrSendMsg = new byte[arrMsg.Length + 1];//加一位标识用于表示是文字消息还是文件
arrSendMsg[0] = 0; // 用来表示发送的是消息数据
Buffer.BlockCopy(arrMsg, 0, arrSendMsg, 1, arrMsg.Length);
socketClient.Send(arrSendMsg);
//获取文件
string dirPath = Application.StartupPath;
byte[] buffer = new byte[1024 * 1024 * 5];
int lenght = socketClient.Receive(buffer);
if (buffer[0] == 1)
{
using (FileStream fs = new FileStream(dirPath + "\\AutoUpdater.xml", FileMode.Create))
{
fs.Write(buffer, 1, lenght - 1);
}
TxtReceiveAddContent("配置文件接收成功:AutoUpdater.xml");//追加提示备注
}
#region 获取XML里需要更新的文件和需要删除的文件
List<string> updatelist = new List<string>();//需要更新的文件集合
List<string> deletelist = new List<string>();//需要更新的文件集合
//获取历史xml文件更新时间以及更新版本
XDocument Olddocument = XDocument.Load(AppDomain.CurrentDomain.BaseDirectory + "AutoUpdater_Back.xml");
//获取到XML的根元素进行操作
XElement Oldroot = Olddocument.Root;
XElement Oldele = Oldroot.Element("UpdateInfo");
//获取旧更新时间标签的值
XElement OldUpdateTime = Oldele.Element("UpdateTime");
//获取旧版本号标签的值
XElement OldVersion = Oldele.Element("Version");
//获取最新xml文件更新时间以及更新版本
XDocument Newdocument = XDocument.Load(AppDomain.CurrentDomain.BaseDirectory + "AutoUpdater.xml");
//获取到XML的根元素进行操作
XElement Newroot = Newdocument.Root;
XElement Newele = Newroot.Element("UpdateInfo");
//获取旧更新时间标签的值
XElement NewUpdateTime = Newele.Element("UpdateTime");
//获取旧版本号标签的值
XElement NewVersion = Newele.Element("Version");
if (NewUpdateTime != OldUpdateTime || NewVersion != OldVersion)
{
//获取需要更新的文件列表
XElement NewUpList = Newroot.Element("UpdateList");
IEnumerable<XElement> UpList = NewUpList.Elements();
foreach (XElement item in UpList)
{
updatelist.Add(item.Value);
}
//获取需要删除的文件列表
XElement NewDelList = Newroot.Element("DeleteList");
IEnumerable<XElement> DelList = NewDelList.Elements();
foreach (XElement item in DelList)
{
deletelist.Add(item.Value);
}
}
#endregion
#region 循环获取更新文件
for (int i = 0; i < updatelist.Count; i++)
{
//发送链接成功提示
byte[] FileName = Encoding.UTF8.GetBytes(updatelist[i]);
byte[] SendFileName = new byte[FileName.Length + 1];//加一位标识用于表示是文字消息还是文件
SendFileName[0] = 0; // 用来表示发送的是消息数据
Buffer.BlockCopy(FileName, 0, SendFileName, 1, FileName.Length);
socketClient.Send(SendFileName);
//获取文件
string FilePath = Application.StartupPath + "\\WebFile";
byte[] bufferByFile = new byte[1024 * 1024 * 50];
int lenghtByFile = socketClient.Receive(bufferByFile);
if (bufferByFile[0] == 1)
{
using (FileStream fs = new FileStream(FilePath + "\\" + updatelist[i], FileMode.Create))
{
fs.Write(bufferByFile, 1, lenghtByFile - 1);
}
TxtReceiveAddContent("文件接收成功:" + updatelist[i]);
}
}
#endregion
#region 循环删除指定文件
for (int i = 0; i < deletelist.Count; i++)
{
try
{
string path = AppDomain.CurrentDomain.BaseDirectory + "\\WebFile\\" + deletelist[i];
File.Delete(path);
TxtReceiveAddContent("删除文件[" + deletelist[i] + "]成功");
}
catch (Exception)
{
TxtReceiveAddContent("删除文件[" + deletelist[i] + "]失败");
continue;
}
}
#endregion
}
catch (Exception ex)
{
File.Move(Newpath, Oldpath);//连接失败,还原文件名
MessageBox.Show(ex.ToString());
throw;
}
调试在客户端进循环的时候服务端侦听不到了
刚接触socket,多谢大佬们解答