I wrote this code which sends an Image between sender and receiver.
First you must run receiver then run sender.
When I test this code on images between 1KB and 1.5KB, it works fine, but when I try to send a larger image, this message appears
cannot evaluate expression because a
native ..........
My code is below, can someone help?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Drawing;
using System.Drawing.Imaging;
using System.Windows.Forms;
using System.Threading;
namespace UPDTester
{
public class UDPClass
{
public Image Merge(Queue<byte[]> myList)
{
int ImgHeight = BitConverter.ToInt32(myList.Dequeue(), 0);
int ImgWidth = BitConverter.ToInt32(myList.Dequeue(), 0);
Bitmap bmp = new Bitmap(ImgWidth, ImgHeight);
Graphics g = Graphics.FromImage(bmp);
int x, y = 0;
while (myList.Count > 0)
{
x = BitConverter.ToInt32(myList.Dequeue(), 0);
y = BitConverter.ToInt32(myList.Dequeue(), 0);
g.DrawImage(ByteToBitmapConverter(myList.Dequeue()), x, y);
}
return bmp;
}
/// <summary>
/// Image Segmentatoin.
/// img: the image that we like to divided.
/// </summary>
public Queue<byte[]> Segmentation(Bitmap img)
{
Queue<byte[]> ByteArray = new Queue<byte[]>();
ByteArray.Enqueue(BitConverter.GetBytes(img.Width));
ByteArray.Enqueue(BitConverter.GetBytes(img.Height));
Image temimg;
for (ushort x = 0; x < img.Width - 5; x += 5)
{
for (ushort y = 0; y < img.Height - 5; y += 5)
{
//temimg = null;
temimg = img.Clone(new Rectangle(x, y, 5, 5), PixelFormat.Format32bppArgb);
ByteArray.Enqueue(BitConverter.GetBytes(x));
ByteArray.Enqueue(BitConverter.GetBytes(y));
ByteArray.Enqueue(ImageToByteConverter(temimg));
}
}
return ByteArray;
}
//Sender
public void SenderUDP(Bitmap img)
{
byte[] data = new byte[1024];
IPEndPoint ipep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 9050);
Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
string welcome = "Hello, are you there?";
data = Encoding.ASCII.GetBytes(welcome);
server.SendTo(data, data.Length, SocketFlags.None, ipep);
IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
EndPoint Remote = (EndPoint)sender;
data = new byte[1024];
int recv = server.ReceiveFrom(data, ref Remote);
MessageBox.Show("Message received from");
MessageBox.Show(Encoding.ASCII.GetString(data, 0, recv));
Queue<byte[]> temlist = Segmentation(img);
data = new byte[1024];
data =temlist.Dequeue();
//Send Width of image.
server.SendTo(data, data.Length, SocketFlags.None, ipep);
data = new byte[1024];
data = temlist.Dequeue();
//Send Height of image.
server.SendTo(data, data.Length, SocketFlags.None, ipep);
data = BitConverter.GetBytes(temlist.Count);
//Send Count of all list.
server.SendTo(data, data.Length, SocketFlags.None, ipep);
MessageBox.Show(temlist.Count.ToString() + " Iam Sender");
while (temlist.Count > 0)
{
server.SendTo(temlist.Dequeue(), Remote);
//MessageBox.Show(temlist.Count.ToString() + "S");
}
//server.Close();
}
//Receiver..(IP, PortNum)
public Image ReceiverUDP()
//public void ReceiverUDP(ref PictureBox pic)
{
int recv;
byte[] data = new byte[1024];
IPEndPoint ipep = new IPEndPoint(IPAddress.Any, 9050);
Socket newsock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
newsock.Bind(ipep);
MessageBox.Show("Waiting for a client....");
//Console.WriteLine("Waiting for a client....");
IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
EndPoint Remote = (EndPoint)(sender);
recv = newsock.ReceiveFrom(data, ref Remote);
MessageBox.Show("Message received from ", Remote.ToString());
MessageBox.Show(Encoding.ASCII.GetString(data, 0, recv));
//Console.WriteLine("Message received from {0}:", Remote.ToString());
//Console.WriteLine(Encoding.ASCII.GetString(data, 0, recv));
string welcome = "Welcome to my test server";
data = Encoding.ASCII.GetBytes(welcome);
newsock.SendTo(data, data.Length, SocketFlags.None, Remote);
Queue<byte[]> TempList = new Queue<byte[]>();
//Receive Width of image.
newsock.ReceiveFrom(data, ref Remote);
TempList.Enqueue(data);
//Receive Height of image.
newsock.ReceiveFrom(data, ref Remote);
TempList.Enqueue(data);
//reccive Count of the list.
newsock.ReceiveFrom(data, ref Remote);
int count = BitConverter.ToInt32(data, 0);
MessageBox.Show(count.ToString() + " Iam Receiver");
data = new byte[1024];
while (count > 0)
{
data = new byte[1024];
newsock.ReceiveFrom(data, ref Remote);
TempList.Enqueue(data);
data = new byte[1024];
newsock.ReceiveFrom(data, ref Remote);
TempList.Enqueue(data);
data = new byte[1024];
newsock.ReceiveFrom(data, ref Remote);
TempList.Enqueue(data);
MessageBox.Show(count.ToString());
count -= 3;
}
return Merge(TempList);
}
private byte[] ImageToByteConverter(Image img)
{
MemoryStream ms = new MemoryStream();
img.Save(ms, ImageFormat.Png);
return ms.ToArray();
}
private Image ByteToBitmapConverter(byte[] buffer)
{
MemoryStream ms = new MemoryStream(buffer);
Image img = Image.FromStream(ms);
return img;
}
}
}
Most likely the reason it locks up is because UDP doesn't guarantee delivery. Packets can be dropped. If that happens, your receive loop is going to sit there waiting forever for a packet that won't ever come.
Related
I have the following code that sends eight images per second to a connected TCP client:
static void HandleServer()
{
Console.WriteLine("Server is starting...");
byte[] data = new byte[1024];
IPEndPoint ipep = new IPEndPoint(IPAddress.Any, 9050);
Socket newsock = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
newsock.Bind(ipep);
newsock.Listen(10);
Console.WriteLine("Waiting for a client...");
Socket client = newsock.Accept();
IPEndPoint newclient = (IPEndPoint)client.RemoteEndPoint;
Console.WriteLine("Connected with {0} at port {1}",
newclient.Address, newclient.Port);
HandleImage(client, newsock);
}
private static void HandleImage(Socket client, Socket s)
{
int sent;
int imageCount = 0;
double totalSize = 0;
try
{
while (true)
{
Image bmp = getImage();
MemoryStream ms = new MemoryStream();
// Save to memory using the bmp format
bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
byte[] bmpBytes = ms.ToArray();
bmp.Dispose();
ms.Close();
sent = SendVarData(client, bmpBytes);
imageCount++;
totalSize += sent;
Console.WriteLine("Sent " + sent + " bytes");
Thread.Sleep(125);
}
}
catch (Exception e)
{
Console.WriteLine("Exception catched, probably an interrupted connection. Restarting server...");
s.Close();
Console.WriteLine("Transferred {0} images with a total size of {1}", imageCount, totalSize);
Console.WriteLine("Average JPEG size: " + totalSize / imageCount + " byte");
HandleServer();
}
}
private static int SendVarData(Socket s, byte[] data)
{
int total = 0;
int size = data.Length;
int dataleft = size;
int sent;
byte[] datasize = new byte[4];
datasize = BitConverter.GetBytes(size);
sent = s.Send(datasize);
while (total < size)
{
sent = s.Send(data, total, dataleft, SocketFlags.None);
total += sent;
dataleft -= sent;
}
return total;
}
}
}
Each image has an average size of 0.046 megabyte, which brought me to a calculated network bandwith of 0.37 megabyte per second for eight images per second.
I monitored the applicaton in the Windows 10 task manager and saw, that the network usage goes up to 35-40 Mbps after two to three seconds.
Could this be in context with my source code?
Thanks a lot
I have a serious problem with this code. This is how it should work:
Client connects to server and choose a file on disk. after that client sends a (byte[] buffer) to the server by this format("File" (4 bytes) + FileNameLength (4 bytes) + FileDataLength (4 bytes)).
After that server creates a (byte[] buffer) with this size (new byte[FileNameLength + FileDataLength]).So client sends a data to the server by this format(byte[] buffer = FileName + FileData). And the server gets a file. The problem is here that i have a MessageBox in the Server to see the FileName after receiving that but MessageBox is always blank and it runs times and times and times.
what's the solution?
The Server:
private Socket SServer = null;
private Socket SClient = null;
private byte[] buffer = new byte[1024];
private byte[] FileNameLength = null;
private byte[] FileSize = null;
private void Server_Load(object sender, EventArgs e)
{
SServer = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
SServer.Bind(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 13000));
SServer.Listen(1);
new Thread(() =>
{
SClient = SServer.Accept();
MessageBox.Show("Connected.");
new Thread(() => Receiver()).Start();
}).Start();
}
private void Receiver()
{
buffer = new byte[1024];
while (true)
{
Int32 AllLength = SClient.Receive(buffer, 0, buffer.Length, SocketFlags.None);
byte[] Devider = new byte[4];
Array.Copy(buffer, 0, Devider, 0, 4);
string Devide = Encoding.ASCII.GetString(Devider);
if (AllLength > 0)
{
if (Devide == "File")
{
FileNameLength = new byte[4];
Array.Copy(buffer, 4, FileNameLength, 0, 4);
FileSize = new byte[4];
Array.Copy(buffer, 8, FileSize, 0, 4);
buffer = null;
buffer = new byte[BitConverter.ToInt32(FileNameLength, 0) + BitConverter.ToInt32(FileSize, 0)];
}
else
{
byte[] FileNameBytes = new byte[BitConverter.ToInt32(FileNameLength, 0)];
Array.Copy(buffer, 0, FileNameBytes, 0, BitConverter.ToInt32(FileNameLength, 0));
byte[] FileBytes = new byte[BitConverter.ToInt32(FileSize, 0)];
Array.Copy(buffer, BitConverter.ToInt32(FileNameLength, 0), FileBytes, 0, BitConverter.ToInt32(FileBytes, 0));
string FileName = Encoding.ASCII.GetString(FileNameBytes);
MessageBox.Show(FileName);
buffer = null;
buffer = new byte[1024];
}
}
}
}
TheClient:
private Socket SClient = null;
string Path, FileName;
private void Client_Load(object sender, EventArgs e)
{
SClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
SClient.Connect(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 13000));
}
private void BT_SendFile_Click(object sender, EventArgs e)
{
byte[] FileLengthBytes = BitConverter.GetBytes(FileName.Length);
byte[] FileBytes = File.ReadAllBytes(Path + FileName);
byte[] buffer = new byte[FileLengthBytes.Length + FileBytes.Length + 4];
//buffer = Encoding.Unicode.GetBytes("File") + FileLengthBytes + FileBytes;
Array.Copy(Encoding.ASCII.GetBytes("File"), 0, buffer, 0, 4);
Array.Copy(FileLengthBytes, 0, buffer, 4, FileLengthBytes.Length);
Array.Copy(BitConverter.GetBytes(FileBytes.Length), 0, buffer, 8, 4);
SClient.Send(buffer, 0, buffer.Length, SocketFlags.None);
byte[] FileNameBytes = Encoding.ASCII.GetBytes(FileName);
buffer = null;
buffer = new byte[FileNameBytes.Length + FileBytes.Length];
Array.Copy(FileNameBytes, 0, buffer, 0, FileNameBytes.Length);
Array.Copy(FileBytes, 0, buffer, FileNameBytes.Length, FileBytes.Length);
SClient.Send(buffer, 0, buffer.Length, SocketFlags.None);
}
private void BT_Browse_Click(object sender, EventArgs e)
{
OpenFileDialog N = new OpenFileDialog();
if (N.ShowDialog() == DialogResult.OK)
{
TB_Address.Text = N.FileName;
string[] Seperate = N.FileName.Split('\\');
FileName = Seperate[Seperate.Length - 1];
Path = null;
foreach (string str in Seperate)
{
if (str != Seperate[Seperate.Length - 1])
Path += str + "\\";
}
}
}
as this friend (Fildor) said, i try to read more about the protocols.
thank you two guys but i think if i separate the file and send it pieces by pieces, i can send the hole file.
I know maybe this is stupid but i think it works.
I'm a newbie and I'm having a small Socket programming exercise.
User input an array from Client and Server calculator it ( + ,* ) and send to client total
This my code but it doesn' run correctly.
My code
Server.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
namespace sv
{
class Program
{
static void Main(string[] args)
{
IPEndPoint iep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 2016);
Socket server = new Socket(AddressFamily.InterNetwork,SocketType.Stream, ProtocolType.Tcp);
server.Bind(iep);
server.Listen(10);
Console.WriteLine("waiting...");
Socket client = server.Accept();
Console.WriteLine("Accept {0}", client.RemoteEndPoint.ToString());
string s = "Welcome";
byte[] data = new byte[1024];
data = Encoding.ASCII.GetBytes(s);
client.Send(data, data.Length, SocketFlags.None);
while (true)
{
data = new byte[1024];
int recv = client.Receive(data);
string c = Encoding.ASCII.GetString(data, 0, recv);
Console.WriteLine("Client: {0}", c);
}
byte[] gdata = new byte[1024];
byte[] total = new byte[1024];
string array;
while (true)
{
int recv = client.Receive(gdata);
array = Encoding.ASCII.GetString(gdata, 0, recv);
Console.WriteLine("Client: {0}", array);
//SUM
int sum = 0;
string[] arrListStr = array.Split(new char[] { ' ' });
for (int i = 0; i < arrListStr.Length; i++)
{
sum += Int32.Parse(arrListStr[i]);
}
array = sum.ToString();
total = Encoding.ASCII.GetBytes(array);
client.Send(total, total.Length, SocketFlags.None);
}
Console.ReadKey();
}
}
}
Client
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
namespace cl
{
class Program
{
static void Main(string[] args)
{
IPEndPoint iep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 2016);
Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
client.Connect(iep);
byte[] data = new byte[1024];
int recv = client.Receive(data);
string s = Encoding.ASCII.GetString(data, 0, recv);
Console.WriteLine("From Server : {0}", s);
string input;
while (true)
{
input = Console.ReadLine();
data = new byte[1024];
data = Encoding.ASCII.GetBytes(input);
client.Send(data, data.Length, SocketFlags.None);
}
data = new byte[1024];
recv = client.Receive(data);
s = Encoding.ASCII.GetString(data, 0, recv);
Console.WriteLine("From Server : {0}, s");
Console.ReadKey();
}
}
}
Pls help me fix it. Thanks <3
change your code like below, it will give you the sum
pass values from client as comma separated like 12,13
server
IPEndPoint iep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 2016);
Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
server.Bind(iep);
server.Listen(10);
Console.WriteLine("waiting...");
Socket client = server.Accept();
Console.WriteLine("Accept {0}", client.RemoteEndPoint.ToString());
string s = "Welcome";
byte[] data = new byte[1024];
data = Encoding.ASCII.GetBytes(s);
client.Send(data, data.Length, SocketFlags.None);
byte[] gdata = new byte[1024];
byte[] total = new byte[1024];
string array;
while (true)
{
int recv = client.Receive(gdata);
array = Encoding.ASCII.GetString(gdata, 0, recv);
Console.WriteLine("Client: {0}", array);
//SUM
int sum = 0;
string[] arrListStr = array.Split(',');
for (int i = 0; i < arrListStr.Length; i++)
{
sum += Int32.Parse(arrListStr[i]);
}
array = sum.ToString();
total = Encoding.ASCII.GetBytes(array);
client.Send(total, total.Length, SocketFlags.None);
}
client
IPEndPoint iep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 2016);
Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
client.Connect(iep);
byte[] data = new byte[1024];
int recv = client.Receive(data);
string s = Encoding.ASCII.GetString(data, 0, recv);
Console.WriteLine("From Server : {0}", s);
string input;
while (true)
{
input = Console.ReadLine();
data = new byte[1024];
data = Encoding.ASCII.GetBytes(input);
client.Send(data, data.Length, SocketFlags.None);
// data = new byte[1024];
recv = client.Receive(data);
s = Encoding.ASCII.GetString(data, 0, recv);
Console.WriteLine("From Server : {0}", s);
Console.ReadKey();
}
I am working on a simple app which sends camera byte stream to c# wpf app using UDP Multicast. I am able to achieve this using UDP Broadcasting.
But what I want is to connect it using UDP multicast but its working for me only if I am using registered multicast IP's like "224.0.0.1".
About my Android Code:
I have written a Service for udp connection which I can call from any activity/fragment. This Service has functions for sending images and texts.
On Camera PreviewCallback
private PreviewCallback previewCb = new PreviewCallback() {
public void onPreviewFrame(byte[] frame, Camera c) {
mService.initSocket();
mService.sendImages(frame);
c.addCallbackBuffer(frame);
}
};
Camera Setup:
Camera.Parameters p = camera_.getParameters();
p.setPreviewSize(procSize_.width, procSize_.height);
//p.setPreviewFormat(ImageFormat.NV21);
p.setPreviewFpsRange(targetMaxFrameRate, targetMinFrameRate);
camera_.setParameters(p);
PixelFormat pixelFormat = new PixelFormat();
PixelFormat.getPixelFormatInfo(ImageFormat.RGB_565, pixelFormat);
int bufSize = procSize_.width * procSize_.height * pixelFormat.bitsPerPixel / 8;
byte[] buffer = null;
for(int i = 0; i < bufNumber; i++) {
buffer = new byte[ bufSize ];
camera_.addCallbackBuffer(buffer);
}
camera_.setPreviewCallbackWithBuffer(cb);
Send Images function:
while(bRunning) {
int sessionNumber = 0;
byte[] buff = msg;
int packets = (int) Math.ceil(buff.length / (float) DATAGRAM_MAX_SIZE);
for (int i = 0; i < packets; i++) {
DatagramPacket packet = new DatagramPacket(data, data.length, localaddress, 11000);
sessionNumber = sessionNumber < MAX_SESSION_NUMBER ? ++sessionNumber : 0;
if(sessionNumber == packets){
bRunning = false;
}
}
}
About my C# code:
I have created a UDPMulticast listener:
IPAddress multicastIP= IPAddress.Parse("224.0.0.1");
UdpClient udpClient = new UdpClient();
IPEndPoint remoteEndPoint = new IPEndPoint(IPAddress.Any, port);
udpClient.MulticastLoopback = true;
udpClient.Client.Bind(remoteEndPoint);
udpClient.JoinMulticastGroup(multicastIP);
byte[] finalBuffer = new byte[80000];
while (true)
{
byte[] buffer = new byte[1048];
buffer = mUDPClient.Receive(ref ipEndPoint);
if (buffer[5].Equals(0))
{
MemoryStream stream = new MemoryStream(finalBuffer);
imgPreview.Source = GetImage(stream);
finalBuffer = new byte[25000];
Array.Copy(buffer, finalBuffer, buffer[4]);
}
else
{
Array.Copy(buffer, finalBuffer, buffer[4]);
}
}
public BitmapImage GetImage(Stream iconStream)
{
var imgbrush = new BitmapImage();
imgbrush.BeginInit();
imgbrush.StreamSource = iconStream;
imgbrush.CreateOptions = BitmapCreateOptions.PreservePixelFormat;
imgbrush.EndInit();
var ib = new ImageBrush(imgbrush);
return imgbrush;
}
Even when I am connected I get an error at imgbrosh.EndIt() saying that the image format is not proper because of which even my first image doesn't get created.
Any help is appreciated, thanks.
I am trying to make an advanced chat in C#. I am not new to programming but it is close to my first TCP chat.
The problem is that my Socket (server) looks to not receive any datas. In my void ReceiveDataListener which is a BackgroundWorker, I added some Console.WriteLine(); to check where it locks and it only display the first Console.WriteLine("Receive Data Listener 0"). I know it is normal that Socket.Receive() lock until some datas are received but it seems to stay locked even if I send datas.
I also want to add that my event onClientConnect and onClientDisconnect are invoked fine so I know the clients connects fine.
Here is the code of my Server class :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;
using System.ComponentModel;
using System.Threading;
namespace JAChat.Library
{
class SocketServer
{
private Socket socket;
private BackgroundWorker bwSocketConnectListener;
private BackgroundWorker bwCheckIfConnected;
private BackgroundWorker bwReceiveDataListener;
private List<ClientManager> clientsList;
#region Constructor
public SocketServer(int port)
{
clientsList = new List<ClientManager>();
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket.Bind(new IPEndPoint(IPAddress.Any, port));
socket.Listen(100);
bwSocketConnectListener = new BackgroundWorker();
bwSocketConnectListener.DoWork += new DoWorkEventHandler(ListenSocketConnection);
bwSocketConnectListener.RunWorkerAsync();
bwCheckIfConnected = new BackgroundWorker();
bwCheckIfConnected.DoWork += CheckIfClientStillConnectedThread;
bwCheckIfConnected.RunWorkerAsync();
bwReceiveDataListener = new BackgroundWorker();
bwReceiveDataListener.DoWork += ReceiveDataListener;
bwReceiveDataListener.RunWorkerAsync();
}
#endregion
#region Getter
public List<ClientManager> connectedClients
{
get
{
return clientsList;
}
}
#endregion
#region Public Methods
/// <summary>
/// Parse and send the command object to targets
/// </summary>
public void sendCommand(Command cmd)
{
BackgroundWorker test = new BackgroundWorker();
test.DoWork += delegate {
foreach(ClientManager cManager in clientsList){
cManager.sendCommand(cmd);
}
};
test.RunWorkerAsync();
}
/// <summary>
/// Disconnect and close the socket
/// </summary>
public void Disconnect()
{
socket.Disconnect(false);
socket.Close();
socket = null; //Stop some background worker
}
#endregion
#region Private Methods
private void ListenSocketConnection(object sender, DoWorkEventArgs e)
{
while (socket != null)
{
//Get and WAIT for new connection
ClientManager newClientManager = new ClientManager(socket.Accept());
clientsList.Add(newClientManager);
onClientConnect.Invoke(newClientManager);
}
}
private void CheckIfClientStillConnectedThread(object sender, DoWorkEventArgs e){
while(socket != null){
for(int i=0;i<clientsList.Count;i++){
if(clientsList[i].socket.Poll(10,SelectMode.SelectRead) && clientsList[i].socket.Available==0){
clientsList[i].socket.Close();
onClientDisconnect.Invoke(clientsList[i]);
clientsList.Remove(clientsList[i]);
i--;
}
}
Thread.Sleep(5);
}
}
private void ReceiveDataListener(object sender, DoWorkEventArgs e){
while (socket != null){
Console.WriteLine("Receive Data Listener 0");
//Read the command's Type.
byte[] buffer = new byte[4];
int readBytes = this.socket.Receive(buffer, 0, 4, SocketFlags.None);
Console.WriteLine("Receive Data Listener 1");
if (readBytes == 0)
break;
Console.WriteLine("Receive Data Listener 2");
CommandType cmdType = (CommandType)(BitConverter.ToInt32(buffer, 0));
Console.WriteLine("Receive Data Listener 3");
//Read the sender IP size.
buffer = new byte[4];
readBytes = this.socket.Receive(buffer, 0, 4, SocketFlags.None);
if (readBytes == 0)
break;
int senderIPSize = BitConverter.ToInt32(buffer, 0);
//Read the sender IP.
buffer = new byte[senderIPSize];
readBytes = this.socket.Receive(buffer, 0, senderIPSize, SocketFlags.None);
if (readBytes == 0)
break;
IPAddress cmdSenderIP = IPAddress.Parse(System.Text.Encoding.ASCII.GetString(buffer));
//Read the sender name size.
buffer = new byte[4];
readBytes = this.socket.Receive(buffer, 0, 4, SocketFlags.None);
if (readBytes == 0)
break;
int senderNameSize = BitConverter.ToInt32(buffer, 0);
//Read the sender name.
buffer = new byte[senderNameSize];
readBytes = this.socket.Receive(buffer, 0, senderNameSize, SocketFlags.None);
if (readBytes == 0)
break;
string cmdSenderName = System.Text.Encoding.Unicode.GetString(buffer);
//Read target IP size.
string cmdTarget = "";
buffer = new byte[4];
readBytes = this.socket.Receive(buffer, 0, 4, SocketFlags.None);
if (readBytes == 0)
break;
int targetIPSize = BitConverter.ToInt32(buffer, 0);
//Read the command's target.
buffer = new byte[targetIPSize];
readBytes = this.socket.Receive(buffer, 0, targetIPSize, SocketFlags.None);
if (readBytes == 0)
break;
cmdTarget = System.Text.Encoding.ASCII.GetString(buffer);
//Read the command's MetaData size.
string cmdMetaData = "";
buffer = new byte[4];
readBytes = this.socket.Receive(buffer, 0, 4, SocketFlags.None);
if (readBytes == 0)
break;
int metaDataSize = BitConverter.ToInt32(buffer, 0);
//Read the command's Meta data.
buffer = new byte[metaDataSize];
readBytes = this.socket.Receive(buffer, 0, metaDataSize, SocketFlags.None);
if (readBytes == 0)
break;
cmdMetaData = System.Text.Encoding.Unicode.GetString(buffer);
//Create the command object
Command cmd = new Command(cmdType, cmdSenderIP, cmdSenderName, IPAddress.Parse(cmdTarget), cmdMetaData);
this.onCommandReceived(cmd);
}
Console.WriteLine("Receive data listener closed");
}
#endregion
#region Events
public delegate void OnClientConnectEventHandler(ClientManager client);
/// <summary>
/// Events invoked when a client connect to the server
/// </summary>
public event OnClientConnectEventHandler onClientConnect = delegate { };
public delegate void OnClientDisconnectEventHandler(ClientManager client);
/// <summary>
/// Events invoked when a client disconnect from the server
/// </summary>
public event OnClientDisconnectEventHandler onClientDisconnect = delegate { };
public delegate void OnCommandReceivedEventHandler(Command cmd);
/// <summary>
/// Events invoked when a command has been sent to the server
/// </summary>
public event OnCommandReceivedEventHandler onCommandReceived = delegate { };
#endregion
}
}
and here is the code that I use to test the server by sending datas :
clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
clientSocket.Connect("localhost", 2000);
networkStream = new NetworkStream(clientSocket);
//CommandType
byte[] buffer = new byte[4];
buffer = BitConverter.GetBytes(1);
this.networkStream.Write(buffer, 0, 4);
this.networkStream.Flush();
//Sender IP + Size
byte[] senderIPBuffer = Encoding.ASCII.GetBytes("192.54.67.8");
buffer = new byte[4];
buffer = BitConverter.GetBytes(senderIPBuffer.Length);
this.networkStream.Write(buffer, 0, 4);
this.networkStream.Flush();
this.networkStream.Write(senderIPBuffer, 0, senderIPBuffer.Length);
this.networkStream.Flush();
//Sender Name + Size
byte[] senderNameBuffer = Encoding.ASCII.GetBytes("James");
buffer = new byte[4];
buffer = BitConverter.GetBytes(senderNameBuffer.Length);
this.networkStream.Write(buffer, 0, 4);
this.networkStream.Flush();
this.networkStream.Write(senderNameBuffer, 0, senderNameBuffer.Length);
this.networkStream.Flush();
//Command Target IP + Size
byte[] targetIPBuffer = Encoding.ASCII.GetBytes("192.43.54.6");
buffer = new byte[4];
buffer = BitConverter.GetBytes(targetIPBuffer.Length);
this.networkStream.Write(buffer, 0, 4);
this.networkStream.Flush();
this.networkStream.Write(targetIPBuffer, 0, targetIPBuffer.Length);
this.networkStream.Flush();
//Command MetaData + Size
byte[] metaBuffer = Encoding.Unicode.GetBytes("Metadata contents");
buffer = new byte[4];
buffer = BitConverter.GetBytes(metaBuffer.Length);
this.networkStream.Write(buffer, 0, 4);
this.networkStream.Flush();
this.networkStream.Write(metaBuffer, 0, metaBuffer.Length);
this.networkStream.Flush();
SocketServer has a class-level variable named "socket"
SocketServer's constructor creates a socket for listening on the specified port and saves this as the value of socket
ListenSocketConnection is calling Socket.Accept (good) and keeping a list of connections
ERROR: ReceiveDataListener is trying to read from the socket that is listening on the specified port instead of reading from the individual sockets that were returned by the Accept call in ListenSocketConnection
Note: the server throws an exception right on startup (for me at least) in ReceiveDataListener, before any client has even attempted to connect, since the socket reader worker immediately tries to read from a socket that is in the listen state.
Hope that helps - Harold