.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);
}
}
}