Тема: Клієнт-сервер, обробка xml, робота з базою MS Access
Програма складається з двох частин: клієнта та сервера.
Робота сервера - обробляти запити від клієнта (приймати та відповідати). Команди формуються в форматі xml. Сервер також працює з базою даних Microsoft Access, де зберігається вся інформація.
Допустимі команди
showDir - показати файли та папки за вказаним шляхом
addDir - cтворити папку за вказаним шляхом
download - завантажити файл за вказаним шляхом
upload - залити файл за вказаним шляхом
rename - переіменувати
task - виконує певну дію (здається пошук по назві файлу) і повертає список
Формат запиту від клієнта (приклад):
<action>
<command>rename</command>
<path>/example/dir</path>
<name>test.txt</name>
<newname>test2.txt</name>
</action>
Формат відповіді сервера
Якщо все відбулось успішно:
ok
Якщо помилка:
false
Клієнт звичайний десктопний додаток, який працює з сервером. Є графічні елементи для відображення списку директорій (типу команди ls (dir) ), завантаження файлу з сервера та відправки файлу на сервер та інші дії, точно не пам'ятаю.
Це все може знадобитись для тих хто почав вивчати C#, .NET (принаймі знає основи).
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Data;
using System.Data.OleDb;
using System.Threading;
using System.Xml;
namespace TestServer
{
class Program
{
static void Main(string[] args)
{
// string xml = "<action><command>upload</command><path>/</path><name>lol.txt</name><data>YWFh</data></action>";
// Console.WriteLine(XmlParse(xml));
// System.Console.ReadKey();
IPEndPoint serverep = new IPEndPoint(IPAddress.Any, 9050);
Socket server = new Socket(
AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp
);
server.Bind(serverep);
server.Listen(10);
Console.WriteLine("Server has successfully started.");
while (true)
{
// Socket client = server.Accept();
// Waits for clients
Socket client = server.Accept();
Thread clientThread = new Thread(delegate() {
ClientThread(client);
});
clientThread.Start();
}
// server.Close();
}
public static string XmlParse(string xml)
{
string response = "";
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
string command = doc.SelectSingleNode("action/command").InnerText;
string path = doc.SelectSingleNode("action/path").InnerText;
if (command == "showDir")
{
OleDbConnection conn = null;
OleDbDataReader dbReader = null;
conn = new OleDbConnection(@"Provider=Microsoft.Jet.OLEDB.4.0; User Id=; Password=; Data Source=files.mdb");
conn.Open();
OleDbCommand query = conn.CreateCommand();
query.CommandText = "SELECT name FROM files WHERE path=\"" +
path + "\"";
dbReader = query.ExecuteReader();
// <?xml ... ?>
doc = new XmlDocument();
XmlNode docNode = doc.CreateXmlDeclaration("1.0", "UTF-8", null);
doc.AppendChild(docNode);
XmlNode actionNode = doc.CreateElement("files");
doc.AppendChild(actionNode);
while (dbReader.Read())
{
XmlNode commandNode = doc.CreateElement("file");
commandNode.InnerText = dbReader.GetString(0);
actionNode.AppendChild(commandNode);
}
conn.Close();
response = doc.OuterXml;
} else if (command == "task")
{
OleDbConnection conn = null;
OleDbDataReader dbReader = null;
conn = new OleDbConnection(@"Provider=Microsoft.Jet.OLEDB.4.0; User Id=; Password=; Data Source=files.mdb");
conn.Open();
OleDbCommand query = conn.CreateCommand();
query.CommandText = "SELECT path+name FROM files WHERE name LIKE '" +
path + "%'";
dbReader = query.ExecuteReader();
// <?xml ... ?>
doc = new XmlDocument();
XmlNode docNode = doc.CreateXmlDeclaration("1.0", "UTF-8", null);
doc.AppendChild(docNode);
XmlNode actionNode = doc.CreateElement("files");
doc.AppendChild(actionNode);
while (dbReader.Read())
{
XmlNode commandNode = doc.CreateElement("file");
commandNode.InnerText = dbReader.GetString(0);
actionNode.AppendChild(commandNode);
}
conn.Close();
response = doc.OuterXml;
} else if (command == "remove")
{
OleDbConnection conn = null;
conn = new OleDbConnection(@"Provider=Microsoft.Jet.OLEDB.4.0; User Id=; Password=; Data Source=files.mdb");
conn.Open();
string name = doc.SelectSingleNode("action/name").InnerText;
OleDbCommand query = conn.CreateCommand();
if (name.Contains('/')) {
query.CommandText = "DELETE FROM files WHERE path like '" + path + name + "%';";
query.ExecuteNonQuery();
}
query.CommandText = "DELETE FROM files WHERE path='" + path + "' AND name='"+ name +"';";
query.ExecuteNonQuery();
conn.Close();
response = "ok";
}
else if (command == "addDir")
{
OleDbConnection conn = null;
conn = new OleDbConnection(@"Provider=Microsoft.Jet.OLEDB.4.0; User Id=; Password=; Data Source=files.mdb");
conn.Open();
string name = doc.SelectSingleNode("action/name").InnerText;
OleDbCommand query;
query = conn.CreateCommand();
query.CommandText = "SELECT count(*) FROM files WHERE name='" + name +
"' and path='" + path + "'";
if ((int) query.ExecuteScalar() == 0)
{
query = conn.CreateCommand();
query.CommandText = "INSERT INTO files (name, path)" +
" VALUES(\'" + name + "\', \'" + path + "\')";
query.ExecuteNonQuery();
}
else
{
return "false";
}
conn.Close();
response = "ok";
}
else if (command == "download")
{
OleDbConnection conn = null;
conn = new OleDbConnection(@"Provider=Microsoft.Jet.OLEDB.4.0; User Id=; Password=; Data Source=files.mdb");
conn.Open();
OleDbCommand query = conn.CreateCommand();
string name = doc.SelectSingleNode("action/name").InnerText;
query.CommandText = "SELECT data FROM files " +
"WHERE path='" + path + "' and name='"+ name +"';";
byte[] data = (byte[]) query.ExecuteScalar();
conn.Close();
// <?xml ... ?>
doc = new XmlDocument();
XmlNode docNode = doc.CreateXmlDeclaration("1.0", "UTF-8", null);
doc.AppendChild(docNode);
XmlNode actionNode = doc.CreateElement("file");
doc.AppendChild(actionNode);
XmlNode dataNode = doc.CreateElement("data");
dataNode.InnerText = Convert.ToBase64String(data);
actionNode.AppendChild(dataNode);
response = doc.OuterXml;
}
else if (command == " ")
{
// Console.WriteLine(xml);
OleDbConnection conn = null;
conn = new OleDbConnection(@"Provider=Microsoft.Jet.OLEDB.4.0; User Id=; Password=; Data Source=files.mdb");
conn.Open();
string name = doc.SelectSingleNode("action/name").InnerText;
string dat = doc.SelectSingleNode("action/data").InnerText;
string query = "INSERT INTO files (name, path, data)" +
" VALUES(@name, @path, @data)";
OleDbCommand command2 = new OleDbCommand(query, conn);
byte[] arr = Convert.FromBase64String(dat);
command2.Parameters.Add("@name", OleDbType.Char).Value = name;
command2.Parameters.Add("@path", OleDbType.Char).Value = path;
command2.Parameters.Add("@data", OleDbType.VarBinary, arr.Length);
command2.Parameters["@data"].Value = arr;
command2.ExecuteNonQuery();
conn.Close();
response = "ok";
}
else if (command == "rename")
{
Console.WriteLine(doc.OuterXml);
OleDbConnection conn = null;
conn = new OleDbConnection(@"Provider=Microsoft.Jet.OLEDB.4.0; User Id=; Password=; Data Source=files.mdb");
conn.Open();
string name = doc.SelectSingleNode("action/name").InnerText;
string newname = doc.SelectSingleNode("action/newname").InnerText;
OleDbCommand query = conn.CreateCommand();
query.CommandText = "UPDATE files SET name='"+newname+"' WHERE path='" + path + "' AND name='" + name + "';";
Console.WriteLine(query.CommandText);
query.ExecuteNonQuery();
conn.Close();
response = "ok";
}
return response;
}
public static void ClientThread(Socket client)
{
byte[] data = new byte[1024 * 1024]; // 1mb
int datalen;
IPEndPoint clientep = (IPEndPoint)client.RemoteEndPoint;
Console.WriteLine("Connected with {0} at port {1}", clientep.Address,
clientep.Port);
while (true)
{
try
{
datalen = client.Receive(data);
client.Send(Encoding.UTF8.GetBytes(
XmlParse(Encoding.UTF8.GetString(data, 0, datalen))
));
Console.WriteLine(Encoding.UTF8.GetString(data, 0, datalen));
}
catch
{
Console.WriteLine("Disconnected from {0}", clientep.Address);
return;
}
}
}
}
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.Xml;
using System.IO;
namespace Lab3Client
{
public partial class Form1 : Form
{
// data
Socket serverSocket;
IPEndPoint ipepServer;
bool isConnected = false;
byte[] data = new byte[1024 * 1024];
public Form1()
{
InitializeComponent();
}
private void buttonConnect_Click(object sender, EventArgs e)
{
string port = inputPort.Text;
string hostname = inputHostname.Text;
if (isConnected)
{
try
{
serverSocket.Close();
isConnected = false;
buttonConnect.Text = "Connect";
label3.Visible = false;
path.Visible = false;
ShowDirectory("clear");
}
catch
{
MessageBox.Show(
"Can not close connection",
"Error");
}
}
else
{
try
{
ipepServer = new IPEndPoint(
IPAddress.Parse(hostname), Int32.Parse(port));
serverSocket = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
serverSocket.Connect(ipepServer);
isConnected = true;
buttonConnect.Text = "Disconnect";
label3.Visible = true;
path.Visible = true;
ShowDirectory("/");
}
catch
{
MessageBox.Show(
"Can not connect to server " + hostname + ":" + port,
"Error");
}
}
}
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
if (isConnected)
{
serverSocket.Close();
}
}
public void ShowDirectory(string dirPath)
{
if (dirPath == "clear")
{
fileList.Items.Clear();
return;
}
if (!isConnected)
{
MessageBox.Show("Client isn't connected to server", "Error");
return;
}
// <?xml ... ?>
XmlDocument doc = new XmlDocument();
XmlNode docNode = doc.CreateXmlDeclaration("1.0", "UTF-8", null);
doc.AppendChild(docNode);
XmlNode actionNode = doc.CreateElement("action");
doc.AppendChild(actionNode);
XmlNode commandNode = doc.CreateElement("command");
commandNode.InnerText = "showDir";
actionNode.AppendChild(commandNode);
XmlNode pathNode = doc.CreateElement("path");
pathNode.InnerText = dirPath;
actionNode.AppendChild(pathNode);
path.Text = dirPath;
serverSocket.Send(Encoding.UTF8.GetBytes(doc.OuterXml));
int datalen = serverSocket.Receive(data);
string str = Encoding.UTF8.GetString(data, 0, datalen);
if (str == "error")
{
MessageBox.Show("Server unknown error", "Error");
return;
}
try
{
doc.LoadXml(str);
XmlNodeList list = doc.SelectNodes("files/file");
fileList.Items.Clear();
if (path.Text != "/")
{
fileList.Items.Add("../");
}
foreach (XmlNode node in list)
{
fileList.Items.Add(node.InnerText);
}
}
catch
{
MessageBox.Show("Server unknown error", "Error");
return;
}
}
private void buttonAddDirectory_Click(object sender, EventArgs e)
{
if (!isConnected)
{
MessageBox.Show("Client isn't connected to server", "Error");
return;
}
// <?xml ... ?>
XmlDocument doc = new XmlDocument();
XmlNode docNode = doc.CreateXmlDeclaration("1.0", "UTF-8", null);
doc.AppendChild(docNode);
XmlNode actionNode = doc.CreateElement("action");
doc.AppendChild(actionNode);
XmlNode commandNode = doc.CreateElement("command");
commandNode.InnerText = "addDir";
actionNode.AppendChild(commandNode);
XmlNode pathNode = doc.CreateElement("path");
pathNode.InnerText = path.Text;
actionNode.AppendChild(pathNode);
XmlNode nameNode = doc.CreateElement("name");
string name = "New folder";
DialogResult res = InputBox("New folder", "Please, input new folder name", ref name);
if (res != DialogResult.OK)
{
return;
}
nameNode.InnerText = name + "/";
actionNode.AppendChild(nameNode);
serverSocket.Send(Encoding.UTF8.GetBytes(doc.OuterXml));
int datalen = serverSocket.Receive(data);
if (Encoding.UTF8.GetString(data, 0, datalen) == "error")
{
MessageBox.Show("Server unknown error", "Error");
return;
}
if (Encoding.UTF8.GetString(data, 0, datalen) == "false")
{
MessageBox.Show("Folder already exists", "Error");
return;
}
ShowDirectory(path.Text);
}
private void buttonRename_Click(object sender, EventArgs e)
{
if (!isConnected)
{
MessageBox.Show("Client isn't connected to server", "Error");
return;
}
if (fileList.SelectedIndex == -1)
{
MessageBox.Show("Please, Choose file or folder", "Error");
return;
}
// <?xml ... ?>
XmlDocument doc = new XmlDocument();
XmlNode docNode = doc.CreateXmlDeclaration("1.0", "UTF-8", null);
doc.AppendChild(docNode);
XmlNode actionNode = doc.CreateElement("action");
doc.AppendChild(actionNode);
XmlNode commandNode = doc.CreateElement("command");
commandNode.InnerText = "rename";
actionNode.AppendChild(commandNode);
XmlNode pathNode = doc.CreateElement("path");
pathNode.InnerText = path.Text;
actionNode.AppendChild(pathNode);
XmlNode nameNode = doc.CreateElement("name");
string name = (string) fileList.SelectedItem;
nameNode.InnerText = name;
actionNode.AppendChild(nameNode);
XmlNode newnameNode = doc.CreateElement("newname");
string newname = "";
DialogResult res = InputBox("Change name", "Please, input new name", ref newname);
if (res != DialogResult.OK)
{
return;
}
if (name.Contains('/'))
{
newnameNode.InnerText = newname + "/";
} else {
newnameNode.InnerText = newname;
}
if (newname == "") {
MessageBox.Show("Please, Input new name", "Error");
return;
}
actionNode.AppendChild(newnameNode);
serverSocket.Send(Encoding.UTF8.GetBytes(doc.OuterXml));
int datalen = serverSocket.Receive(data);
if (Encoding.UTF8.GetString(data, 0, datalen) == "error")
{
MessageBox.Show("Server unknown error", "Error");
return;
}
ShowDirectory(path.Text);
}
private void buttonRemove_Click(object sender, EventArgs e)
{
if (!isConnected)
{
MessageBox.Show("Client isn't connected to server", "Error");
return;
}
if (fileList.SelectedIndex == -1)
{
MessageBox.Show("Please, Choose file or folder", "Error");
return;
}
// <?xml ... ?>
XmlDocument doc = new XmlDocument();
XmlNode docNode = doc.CreateXmlDeclaration("1.0", "UTF-8", null);
doc.AppendChild(docNode);
XmlNode actionNode = doc.CreateElement("action");
doc.AppendChild(actionNode);
XmlNode commandNode = doc.CreateElement("command");
commandNode.InnerText = "remove";
actionNode.AppendChild(commandNode);
XmlNode pathNode = doc.CreateElement("path");
pathNode.InnerText = path.Text;
actionNode.AppendChild(pathNode);
XmlNode nameNode = doc.CreateElement("name");
string name = (string) fileList.SelectedItem;
nameNode.InnerText = name;
actionNode.AppendChild(nameNode);
serverSocket.Send(Encoding.UTF8.GetBytes(doc.OuterXml));
int datalen = serverSocket.Receive(data);
if (Encoding.UTF8.GetString(data, 0, datalen) == "error")
{
MessageBox.Show("Server unknown error", "Error");
return;
}
ShowDirectory(path.Text);
}
private void buttonUpload_Click(object sender, EventArgs e)
{
if (!isConnected)
{
MessageBox.Show("Client isn't connected to server", "Error");
return;
}
// <?xml ... ?>
XmlDocument doc = new XmlDocument();
XmlNode docNode = doc.CreateXmlDeclaration("1.0", "UTF-8", null);
doc.AppendChild(docNode);
XmlNode actionNode = doc.CreateElement("action");
doc.AppendChild(actionNode);
XmlNode commandNode = doc.CreateElement("command");
commandNode.InnerText = "upload";
actionNode.AppendChild(commandNode);
XmlNode pathNode = doc.CreateElement("path");
pathNode.InnerText = path.Text;
actionNode.AppendChild(pathNode);
OpenFileDialog dialog = new OpenFileDialog();
if (dialog.ShowDialog() != DialogResult.OK)
{
return;
}
Stream stream = dialog.OpenFile();
XmlNode nameNode = doc.CreateElement("name");
nameNode.InnerText = dialog.FileName;
int index = nameNode.InnerText.LastIndexOf('\\');
nameNode.InnerText = nameNode.InnerText.Substring(index + 1);
actionNode.AppendChild(nameNode);
XmlNode dataNode = doc.CreateElement("data");
data = new byte[1024 * 1024];
int len = stream.Read(data, 0, 1024 * 1024);
dataNode.InnerText = Convert.ToBase64String(data, 0, len);
actionNode.AppendChild(dataNode);
serverSocket.Send(Encoding.UTF8.GetBytes(doc.OuterXml));
int datalen = serverSocket.Receive(data);
if (Encoding.UTF8.GetString(data, 0, datalen) == "error")
{
MessageBox.Show("Server unknown error", "Error");
return;
}
stream.Close();
ShowDirectory(path.Text);
}
private void buttonDownload_Click(object sender, EventArgs e)
{
if (!isConnected)
{
MessageBox.Show("Client isn't connected to server", "Error");
return;
}
if (fileList.SelectedIndex == -1)
{
MessageBox.Show("Please, Choose file to download", "Error");
return;
}
XmlDocument doc = new XmlDocument();
XmlNode docNode = doc.CreateXmlDeclaration("1.0", "UTF-8", null);
doc.AppendChild(docNode);
XmlNode actionNode = doc.CreateElement("action");
doc.AppendChild(actionNode);
XmlNode commandNode = doc.CreateElement("command");
commandNode.InnerText = "download";
actionNode.AppendChild(commandNode);
XmlNode pathNode = doc.CreateElement("path");
pathNode.InnerText = path.Text;
actionNode.AppendChild(pathNode);
XmlNode nameNode = doc.CreateElement("name");
nameNode.InnerText = (string) fileList.SelectedItem;
actionNode.AppendChild(nameNode);
serverSocket.Send(Encoding.UTF8.GetBytes(doc.OuterXml));
int datalen = serverSocket.Receive(data);
if (Encoding.UTF8.GetString(data, 0, datalen) == "error")
{
MessageBox.Show("Server unknown error", "Error");
return;
}
SaveFileDialog dialog = new SaveFileDialog();
dialog.FileName = (string) fileList.SelectedItem;
if (dialog.ShowDialog() != DialogResult.OK)
{
return;
}
doc.LoadXml(Encoding.UTF8.GetString(data, 0, datalen));
byte[] convertdata = Convert.FromBase64String(doc.SelectSingleNode("file/data").InnerText);
Stream s = dialog.OpenFile();
s.Write(convertdata, 0, convertdata.Length);
s.Close();
ShowDirectory(path.Text);
}
private void fileList_SelectedIndexChanged(object sender, EventArgs e)
{
}
public static DialogResult InputBox(string title, string promptText, ref string value)
{
Form form = new Form();
Label label = new Label();
TextBox textBox = new TextBox();
Button buttonOk = new Button();
Button buttonCancel = new Button();
form.Text = title;
label.Text = promptText;
textBox.Text = value;
buttonOk.Text = "OK";
buttonCancel.Text = "Cancel";
buttonOk.DialogResult = DialogResult.OK;
buttonCancel.DialogResult = DialogResult.Cancel;
label.SetBounds(9, 20, 372, 13);
textBox.SetBounds(12, 36, 372, 20);
buttonOk.SetBounds(228, 72, 75, 23);
buttonCancel.SetBounds(309, 72, 75, 23);
label.AutoSize = true;
textBox.Anchor = textBox.Anchor | AnchorStyles.Right;
buttonOk.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
buttonCancel.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
form.ClientSize = new Size(396, 107);
form.Controls.AddRange(new Control[] { label, textBox, buttonOk, buttonCancel });
form.ClientSize = new Size(Math.Max(300, label.Right + 10), form.ClientSize.Height);
form.FormBorderStyle = FormBorderStyle.FixedDialog;
form.StartPosition = FormStartPosition.CenterScreen;
form.MinimizeBox = false;
form.MaximizeBox = false;
form.AcceptButton = buttonOk;
form.CancelButton = buttonCancel;
DialogResult dialogResult = form.ShowDialog();
value = textBox.Text;
return dialogResult;
}
private void fileList_MouseDoubleClick(object sender, MouseEventArgs e)
{
if (fileList.SelectedIndex == -1)
{
return;
}
string item = fileList.SelectedItem.ToString();
// check - is folder?
if (item.Contains('/'))
{
// folder
if (item == "../")
{
string subpath = path.Text.Substring(0, path.Text.Length - 1);
int pos = subpath.LastIndexOf('/') + 1;
ShowDirectory(subpath.Substring(0, pos));
}
else
{
ShowDirectory(path.Text + item);
}
}
else
{
buttonDownload_Click(sender, e);
}
}
private void button1_Click(object sender, EventArgs e)
{
if (!isConnected)
{
MessageBox.Show("Client isn't connected to server", "Error");
return;
}
// <?xml ... ?>
XmlDocument doc = new XmlDocument();
XmlNode docNode = doc.CreateXmlDeclaration("1.0", "UTF-8", null);
doc.AppendChild(docNode);
XmlNode actionNode = doc.CreateElement("action");
doc.AppendChild(actionNode);
XmlNode commandNode = doc.CreateElement("command");
commandNode.InnerText = "task";
actionNode.AppendChild(commandNode);
string tmpstr = "n";
XmlNode startNode = doc.CreateElement("path");
if (DialogResult.OK != InputBox("InputBox","Input beginnig of file", ref tmpstr)) {
return;
}
startNode.InnerText = tmpstr;
actionNode.AppendChild(startNode);
serverSocket.Send(Encoding.UTF8.GetBytes(doc.OuterXml));
int datalen = serverSocket.Receive(data);
string str = Encoding.UTF8.GetString(data, 0, datalen);
if (str == "error")
{
MessageBox.Show("Server unknown error", "Error");
return;
}
try
{
doc.LoadXml(str);
XmlNodeList list = doc.SelectNodes("files/file");
StringBuilder builder = new StringBuilder();
foreach (XmlNode node in list)
{
builder.Append(node.InnerText);
builder.Append("\n");
}
MessageBox.Show(builder.ToString(), "Results");
}
catch
{
MessageBox.Show("Server unknown error", "Error");
return;
}
}
}
}
Прикріпив також проекти Visual Studio (здається 2008 версія)
client-server.zip 638.68 kb, 445 downloads since 2013-04-14