.NET 3.x Clients-Server Socket - C#
Формулировка задачи:
Доброго времени суток. Сижу пишу дипломную работу по роботе с Socket, но проблема в том то я не когда с ними не работал, у меня на данный момент реализовано полною работу со стороны клиента к серверу, то есть передача сообщений и приём их на сервере. Но сейчас у меня возникли кое-какие вопросы:
1) Мне надо реализовать передачу данных от сервера до клиента вот весь мой код:
Вроде-бы все отлично работает, но когда я начинаю писать DataReceived на стороне клиента и Send на стороне сервера, то в клиенте вылетает ошибка со стороны клиента в Client.cs:
2 ) Как по сете можно передать записи из базы данных, что-то типа DbDataRecord.
Заранее спасибо.
using System; using System.IO; using System.Net; using System.Net.Sockets; namespace MachineEmulatorServer { internal enum Commands { Command = 0, DbDataRecord = 1 } struct ReceiveBuffer { private const int bufferSize = 1024; public byte[] buffer; public int toReceive; public readonly MemoryStream bufStream; public ReceiveBuffer(int toRec) { buffer = new byte[bufferSize]; toReceive = toRec; bufStream = new MemoryStream(toRec); } public void Dispose() { buffer = null; toReceive = 0; Close(); if (bufStream != null) bufStream.Dispose(); } private void Close() { if (bufStream != null && bufStream.CanWrite) bufStream.Close(); } } class Client { private byte[] lenBuffer; private ReceiveBuffer buffer; private Socket socket; public IPEndPoint EndPoint { get { if (socket != null && socket.Connected) return (IPEndPoint)socket.RemoteEndPoint; return new IPEndPoint(IPAddress.None, 0); } } public delegate void DisconectedEventHandler(Client sender); public delegate void DataReceivedHandler(Client sender, ReceiveBuffer e); public delegate void DataSendHandler(Client sender, int send); public event DisconectedEventHandler Discotected; public event DataReceivedHandler DataReceived; public event DataSendHandler OnSend; public Client(Socket s) { socket = s; lenBuffer = new byte[4]; } public void Send(byte[] data, int index, int length) { socket.BeginSend(BitConverter.GetBytes(length), 0, 4, SocketFlags.None, SendCallBack, null); socket.BeginSend(data, index, length, SocketFlags.None, SendCallBack, null); } private void SendCallBack(IAsyncResult ar) { try { var send = socket.EndSend(ar); if (OnSend != null) { OnSend(this, send); } } catch (Exception ex) { Console.WriteLine("Send error\n {0}", ex.Message); } } public void Close() { if (socket != null) { socket.Disconnect(false); socket.Close(); } buffer.Dispose(); socket = null; lenBuffer = null; Discotected = null; DataReceived = null; } public void ReceiveAsync() { socket.BeginReceive(lenBuffer, 0, lenBuffer.Length, SocketFlags.None, ReceiveCallBack, null); } private void ReceiveCallBack(IAsyncResult ar) { try { var rec = socket.EndReceive(ar); if (rec == 0) { if (Discotected != null) { Discotected(this); return; } if (rec != 4) { throw new Exception(); } } } catch (SocketException se) { switch (se.SocketErrorCode) { case SocketError.ConnectionAborted: case SocketError.ConnectionReset: if (Discotected != null) { Discotected(this); return; } break; } } catch (ObjectDisposedException) { return; } catch (NullReferenceException) { return; } catch (Exception ex) { Console.Write(ex.Message); return; } buffer = new ReceiveBuffer(BitConverter.ToInt32(lenBuffer, 0)); socket.BeginReceive(buffer.buffer, 0, buffer.buffer.Length, SocketFlags.None, ReceivePacketCallBack, null); } void ReceivePacketCallBack(IAsyncResult ar) { var rec = socket.EndReceive(ar); if (rec <= 0) return; buffer.bufStream.Write(buffer.buffer, 0, rec); buffer.toReceive -= rec; if (buffer.toReceive > 0) { Array.Clear(buffer.buffer, 0, buffer.buffer.Length); socket.BeginReceive(buffer.buffer, 0, buffer.buffer.Length, SocketFlags.None, ReceivePacketCallBack, null); return; } if (DataReceived != null) { buffer.bufStream.Position = 0; DataReceived(this, buffer); } buffer.Dispose(); ReceiveAsync(); } } }
using System; using System.Net; using System.Net.Sockets; namespace MachineEmulatorServer { class Listener { public delegate void SocketAcceptedHandler(Socket e); public event SocketAcceptedHandler Accepted; private Socket listener; public bool Running { get; private set; } public void Start(int port) { if (Running) return; listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); listener.Bind(new IPEndPoint(0, port)); listener.Listen(0); listener.BeginAccept(AcceptedCallBack, null); Running = true; } public void Stop() { if (!Running) return; listener.Close(); Running = false; } private void AcceptedCallBack(IAsyncResult ar) { try { var s = listener.EndAccept(ar); if (Accepted != null) { Accepted(s); } } catch (Exception e) { } if (!Running) return; try { listener.BeginAccept(AcceptedCallBack, null); } catch (Exception) { } } } }
using System.Collections.Generic; using System.IO; using System.Windows.Forms; namespace MachineEmulatorServer { public partial class Form1 : Form { private Listener listener; private readonly List<Client> clients; public Form1() { InitializeComponent(); FormClosing += Form1_FormClosing; clients = new List<Client>(); } private void Form1_FormClosing(object sender, FormClosingEventArgs e) { while (clients.Count != 0) { clients[0].Close(); clients.Remove(clients[0]); } if (listener != null && listener.Running) listener.Stop(); } private void Form1_Load(object sender, System.EventArgs e) { listener = new Listener(); listener.Accepted += listener_Accepted; listener.Start(5053); } private void listener_Accepted(System.Net.Sockets.Socket e) { var newClient = new Client(e); newClient.DataReceived += client_DataReceived; newClient.Discotected += client_Discotected; newClient.OnSend += newClient_OnSend; newClient.ReceiveAsync(); SendText("You connected", newClient); if (clients == null) return; clients.Add(newClient); Invoke((MethodInvoker) delegate { TextLogger.Text += "Connected:" + newClient.EndPoint + "\n"; }); } private static void SendText(string text, Client client) { var bw = new BinaryWriter(new MemoryStream()); bw.Write((int)Commands.Command); bw.Write(text); bw.Close(); var data = ((MemoryStream)bw.BaseStream).ToArray(); bw.BaseStream.Dispose(); client.Send(data, 0, data.Length); } void newClient_OnSend(Client sender, int send) { TextLogger.Text += "Send to: " + sender.EndPoint + "\n"; } private void client_Discotected(Client sender) { for (var i = 0; i < clients.Count; i++) { if (!Equals(clients[i].EndPoint, sender.EndPoint)) continue; Invoke((MethodInvoker) delegate { TextLogger.Text += "Disconnected: " + clients[i].EndPoint + "\n"; }); clients[i].Close(); clients.Remove(clients[i]); break; } } private void client_DataReceived(Client sender, ReceiveBuffer e) { var r = new BinaryReader(e.bufStream); var header = (Commands) r.ReadInt32(); switch (header) { case Commands.Command: { var s = r.ReadString(); Invoke((MethodInvoker) (() => TextLogger.Text += s + "\n")); } break; case Commands.DbDataRecord: { var imageBytesLen = r.ReadInt32(); r.ReadBytes(imageBytesLen); r.ReadString(); Invoke((MethodInvoker) delegate { //pbImage.Image = Image.FromStream(new MemoryStream(iBytes)); }); } break; } } } }
using System; using System.IO; using System.Net.Sockets; namespace MachineEmulatorUsers { internal enum Commands { Command = 0, DbDataRecord = 1 } struct ReceiveBuffer { private const int bufferSize = 1024; public byte[] buffer; public int toReceive; public readonly MemoryStream bufStream; public ReceiveBuffer(int toRec) { buffer = new byte[bufferSize]; toReceive = toRec; bufStream = new MemoryStream(toRec); } public void Dispose() { buffer = null; toReceive = 0; Close(); if (bufStream != null) bufStream.Dispose(); } private void Close() { if (bufStream != null && bufStream.CanWrite) bufStream.Close(); } } internal class Client { private byte[] lenBuffer; private ReceiveBuffer buffer; private Socket socket; public delegate void OnConnectEventHandler(Client sender, bool connected); public delegate void OnSendEventHandler(Client sender, int send); public delegate void DataReceivedHandler(Client sender, ReceiveBuffer e); public delegate void OnDisconnectEventHandler(Client sender); public event OnConnectEventHandler OnConnect; public event OnSendEventHandler OnSend; public event OnDisconnectEventHandler OnDisconnect; public event DataReceivedHandler DataReceived; private bool Connected { get { return socket != null && socket.Connected; } } public Client() { socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); } public void Connect(string ipAddress, int port) { if (socket == null) socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); socket.BeginConnect(ipAddress, port, ConnectCallBack, null); } private void ConnectCallBack(IAsyncResult ar) { try { socket.EndConnect(ar); if (OnConnect != null) { OnConnect(this, Connected); } } catch (Exception) { } } public void Send(byte[] data, int index, int length) { if (!Connected) return; socket.BeginSend(BitConverter.GetBytes(length), 0, 4, SocketFlags.None, SendCallBack, null); socket.BeginSend(data, index, length, SocketFlags.None, SendCallBack, null); } private void SendCallBack(IAsyncResult ar) { try { var send = socket.EndSend(ar); if (OnSend != null) { OnSend(this, send); } } catch (Exception ex) { Console.WriteLine("Send error\n {0}", ex.Message); } } public void Disconnect() { try { if (!socket.Connected) return; socket.Close(); socket = null; if (OnDisconnect != null) { OnDisconnect(this); } } catch (Exception) { } } public void ReceiveAsync() { socket.BeginReceive(lenBuffer, 0, lenBuffer.Length, SocketFlags.None, ReceiveCallBack, null); } private void ReceiveCallBack(IAsyncResult ar) { try { var rec = socket.EndReceive(ar); if (rec == 0) { if (rec != 4) { throw new Exception(); } } } catch (SocketException se) { switch (se.SocketErrorCode) { case SocketError.ConnectionAborted: case SocketError.ConnectionReset: Disconnect(); break; } } catch (ObjectDisposedException) { return; } catch (NullReferenceException) { return; } catch (Exception ex) { Console.Write(ex.Message); return; } buffer = new ReceiveBuffer(BitConverter.ToInt32(lenBuffer, 0)); socket.BeginReceive(buffer.buffer, 0, buffer.buffer.Length, SocketFlags.None, ReceivePacketCallBack, null); } void ReceivePacketCallBack(IAsyncResult ar) { var rec = socket.EndReceive(ar); if (rec <= 0) return; buffer.bufStream.Write(buffer.buffer, 0, rec); buffer.toReceive -= rec; if (buffer.toReceive > 0) { Array.Clear(buffer.buffer, 0, buffer.buffer.Length); socket.BeginReceive(buffer.buffer, 0, buffer.buffer.Length, SocketFlags.None, ReceivePacketCallBack, null); return; } if (DataReceived != null) { buffer.bufStream.Position = 0; DataReceived(this, buffer); } buffer.Dispose(); ReceiveAsync(); } } }
using System; using System.ComponentModel; using System.Data.Common; using System.Drawing; using System.IO; using System.Threading; using System.Windows.Forms; namespace MachineEmulatorUsers { public partial class Form1 : Form { private readonly Client client; private bool connect; private DbDataRecord dataRecords; private BackgroundWorker background; private string errorMessage; public Form1() { InitializeComponent(); client = new Client(); client.OnConnect += client_onConnect; client.OnDisconnect += client_onDisconnect; client.OnSend += client_onSend; FormClosing += Form1_FormClosing; } private void Form1_Load(object sender, EventArgs e) { client.Connect("127.0.0.1", 5053); Thread.Sleep(1500); background = new BackgroundWorker { WorkerReportsProgress = true, WorkerSupportsCancellation = true }; background.DoWork += bw_DoWork; background.ProgressChanged += bw_ProgressChanged; background.RunWorkerCompleted += bw_RunWorkerCompleted; if (connect) { LoadGroupBox.Visible = true; client.DataReceived+=Server_DataReceived; client.ReceiveAsync(); return; } ErrorLabel.Visible = true; errorMessage = "Кліент не знайшов з'єднання з Сервером...\nКлієн буде завершено через "; background.RunWorkerAsync(); } void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { Close(); } void bw_ProgressChanged(object sender, ProgressChangedEventArgs e) { ErrorLabel.Text = errorMessage + e.ProgressPercentage; } private static void bw_DoWork(object sender, DoWorkEventArgs e) { var worker = sender as BackgroundWorker; for (var i = 10; i > 0; i--) { if (worker != null && worker.CancellationPending) { e.Cancel = true; break; } Thread.Sleep(500); if (worker != null) worker.ReportProgress(i); } } void Form1_FormClosing(object sender, FormClosingEventArgs e) { if (client != null) client.Disconnect(); } void client_onSend(Client sender, int send) { Invoke((MethodInvoker) delegate { Text = string.Format("Data sent: {0}", send); }); } private void client_onConnect(Client sender, bool connected) { connect = connected; } private void client_onDisconnect(Client sender) { connect = false; } private void InsertText(object sender, EventArgs e) { var s = sender as PictureBox; if (s != null) textBox1.Text += ((PictureBox) sender).Tag; } private void StartButtonClick(object sender, EventArgs e) { LoadContent(); LoadGroupBox.Visible = false; KeyBoard.Visible = true; button1.Visible = true; textBox1.Visible = true; } private void button1_Click(object sender, EventArgs e) { SendText(textBox1.Text); } void SendText(string text) { var bw = new BinaryWriter(new MemoryStream()); bw.Write((int)Commands.Command); bw.Write(text); bw.Close(); var data = ((MemoryStream) bw.BaseStream).ToArray(); bw.BaseStream.Dispose(); client.Send(data, 0, data.Length); } private void Server_DataReceived(Client sender, ReceiveBuffer e) { var r = new BinaryReader(e.bufStream); var header = (Commands) r.ReadInt32(); switch (header) { case Commands.Command: { var s = r.ReadString(); Invoke((MethodInvoker) (() => ExecuteCommand(s))); } break; case Commands.DbDataRecord: { var s = r.ReadString(); Invoke((MethodInvoker)(() => MessageBox.Show(s))); } break; } } private void ExecuteCommand(String com) { if (com != "Disconnected") return; errorMessage = "Клієнт був відключений сервером...\nКлієн буде завершено через "; background.RunWorkerAsync(); } } }
public void ReceiveAsync() { socket.BeginReceive(lenBuffer, 0, lenBuffer.Length, SocketFlags.None, ReceiveCallBack, null); //Exception: NullReferenceException - в экземпляре объекта не указана ссылка на объект. }
Тема все еще актуальна.
Решение задачи: «.NET 3.x Clients-Server Socket»
textual
Листинг программы
private void BackgroundReconnectDoWork(object sender, DoWorkEventArgs e) { var worker = sender as BackgroundWorker; var flag = false; while (flag != true) { Invoke((MethodInvoker) (delegate { client = new Client(); client.Connect(adress, port); Thread.Sleep(375); flag = connect; })); for (var i = 9; i >= 0; i--) { if (worker != null && worker.CancellationPending) { e.Cancel = true; break; } Thread.Sleep(500); if (worker != null) worker.ReportProgress(i); } } }
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д