How to use UnixDomainSocketEndPoint to create a unix socket in dotnet? - c#

I have a program that was written on C that needs to send data to another application written on C#.
Can someone show a basic hello world example on how to make use of UnixDomainSocketEndPoint on linux? . I will like the c# application to be the server. In other words the C application will send data to the C# application. How can I create a unix socket that will be listening for data on dotnet (the application does not need to reply nothing back) ?
When researching on the internet all the stuff I find is relevant to mono such as this question:
How to connect to a Unix Domain Socket in .NET Core in C# . I tried that example and it did not work. Moreover it does not make use of UnixDomainSocketEndPoint.
I also found this tutorial https://medium.com/#goelhardik/http-connection-to-unix-socket-from-dotnet-core-in-c-21d19ef08f8a that uses the same code.

Maybe there are not that many examples on the internet because it is more simple than I thought. I was able to answer the question without researching on the internet. I should had tried it before asking. Anyways here is the answer:
using System;
using System.Net.Sockets;
using System.Threading.Tasks;
class Program
{
static void Main(string[] args)
{
var path = "/tmp/foo.sock";
// client
Task.Run(async () =>
{
// wait 2 seconds
await Task.Delay(2000);
using (var socket = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.Unspecified))
{
socket.Connect(new UnixDomainSocketEndPoint(path));
// send hello world
var dataToSend = System.Text.Encoding.UTF8.GetBytes("Hello-world!");
socket.Send(dataToSend);
}
});
// Server
{
// delete file if it exists
if (System.IO.File.Exists(path))
System.IO.File.Delete(path);
var socket = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.Unspecified);
socket.Bind(new UnixDomainSocketEndPoint(path));
socket.Listen(5);
Console.WriteLine("Server started waiting for client to connect...");
var s = socket.Accept();
Console.WriteLine("Client connected");
var buffer = new byte[1024];
var numberOfBytesReceived = s.Receive(buffer, 0, buffer.Length, SocketFlags.None);
var message = System.Text.Encoding.UTF8.GetString(buffer, 0, numberOfBytesReceived);
Console.WriteLine($"Received: {message}");
}
}
}

Related

C# UDPClient - Sending and Receiving to a program on local machine

I have two third party programs running on my PC which communicate with each other via UDP. Program A is simply a user-interface application which connects via UDP and allows the user to send specific hex commands to program B which sends back some acknowledgement in hex. I know that program B receives on port 11001 and sends on port 11000. I am trying to recreate program A myself in C# as a console application to start with. I've written the following code:
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
network udpNetwork = new network();
Console.WriteLine("Hello World!");
udpNetwork.StartListener();
}
}
class network
{
private const int sendPort = 11001; //Port to transmit to
private const int receivePort = 11000; //Port to receive on
public void StartListener()
{
string IP_Address = Dns.GetHostByName(Environment.MachineName).AddressList[1].ToString();
IPAddress broadcast = IPAddress.Parse(IP_Address); //create IP address
IPEndPoint endpointSend = new IPEndPoint(broadcast, sendPort);
IPEndPoint endpointReceive = new IPEndPoint(broadcast, receivePort);
UdpClient udpServer = new UdpClient(AddressFamily.InterNetwork);
udpServer.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
udpServer.Client.Bind(endpointSend);
var packetData = new byte[] { 0x1F, 0x7F, 0x80, 0x1F, 0xFF };
try
{
udpServer.Connect(endpointSend);
udpServer.Send(packetData, packetData.Length);
udpServer.Close();
UdpClient udpReceive = new UdpClient(AddressFamily.InterNetwork);
udpReceive.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
udpReceive.Client.Bind(endpointReceive);
Byte[] receiveBytes = udpReceive.Receive(ref endpointReceive);
string returnData = Encoding.ASCII.GetString(receiveBytes);
Console.WriteLine("This is the message you received " +
returnData.ToString());
} catch(Exception e)
{
Console.WriteLine(e.ToString());
}
}
}
}
The code runs fine until the line Byte[] receiveBytes = udpReceive.Receive(ref endpointReceive); where it hangs. I read that this function is blocking which means that the program is waiting for data but obviously not receiving any. Program B listening on port 11001 should send back a response after I have sent the packetData but doesn't. I don't have anyway to use program B to confirm that it is getting the data I am sending. How could I confirm that Program B receives my data in the first place, or do I have some other issue with my code?
edit:
I have edited my code to make use of IPV4 rather than IPV6 as per Jdweng's suggestion. (Shown corrected in the code snippet above). Program B is however still not receiving any data which I can confirm by using TCPView. After launchign the program from within Visual Studio 2019 TCPView shows that there were no received packets by Program B.

C# Receive Multicast UDP in multiple programs on the same machine?

Thanks in advance for any help.
There is a program, not written by me that sends UDP multicast packets of info on the local LAN. I've looked the source and it appears they are correctly setup to multicast. This program is WSJT-X which if you are a Ham operator you might have heard of.
The UDP packets contain over the air signal decodes so lots of other programs including mine are interested in these packets.
The problem I'm having is that my UDP receive seems to consume the messages so no other software running on the same machine seems to receive them once my test software starts up.
Here is simple receiver:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
namespace ReadUDP
{
internal class Program
{
private static void Main(string[] args)
{
// Setup
int port = 2237;
var multicastIP = IPAddress.Parse("225.0.0.1");
// Create endpoints
var remoteEndPoint = new IPEndPoint(multicastIP, port);
var localEndPoint = new IPEndPoint(IPAddress.Any, port);
// Create and configure UdpClient
var udpclient = new UdpClient();
udpclient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
udpclient.ExclusiveAddressUse = false;
udpclient.Client.MulticastLoopback = true;
udpclient.MulticastLoopback = true;
// Bind, Join
udpclient.Client.Bind(localEndPoint);
udpclient.JoinMulticastGroup(multicastIP, IPAddress.Any);
Task.Run(() =>
{
IPEndPoint sender = new IPEndPoint(0, 0);
while (true)
{
var recvBuffer = udpclient.Receive(ref sender);
var recvStr = Encoding.UTF8.GetString(recvBuffer);
Console.WriteLine("--------------------------------------------------------------------------");
Console.WriteLine($"From:{sender} Data:{recvStr}");
Console.WriteLine("--------------------------------------------------------------------------");
}
});
Console.ReadLine();
}
}
}
This simple program receives the data sent by WSJT-X just fine.
If I clone this project to a new directory, build a new copy of the program and run it, the copy never receives any of the broadcast data while the first copy is running. Only the first running copy gets data.
If I shutdown the first copy then the second copy starts to receive the data.
This acts like the first copy is consuming the message and no other clients receive it. I'm trying to prevent that. I just want to in effect, "peek" at the messages and allow other clients to receive them.
I've tried a a bunch of different options and settings, I've looked at many examples but I have not been able to solve this issue.
Any help would be greatly appreciated.
For those of you that don't have WSJT-X, the following simple UDP sender will send UDP packets:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
namespace ReadUDP
{
internal class Program
{
private static void Main(string[] args)
{
// Setup
int port = 2237;
var multicastIP = IPAddress.Parse("225.0.0.1");
// Create endpoints
var remoteEndPoint = new IPEndPoint(multicastIP, port);
var localEndPoint = new IPEndPoint(IPAddress.Any, port);
// Create and configure UdpClient
var udpclient = new UdpClient();
udpclient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
udpclient.ExclusiveAddressUse = false;
udpclient.Client.MulticastLoopback = true;
udpclient.MulticastLoopback = true;
// Bind, Join
udpclient.Client.Bind(localEndPoint);
udpclient.JoinMulticastGroup(multicastIP, IPAddress.Any);
Task.Run(() =>
{
int msgnum = 1;
while (true)
{
var msg = $"Sending message {msgnum++}";
Console.WriteLine("--------------------------------------------------------------------------");
Console.WriteLine($"Send: {msg}");
Console.WriteLine("--------------------------------------------------------------------------");
var bytes = Encoding.UTF8.GetBytes(msg);
udpclient.Send(bytes, bytes.Length, remoteEndPoint);
Task.Delay(2000).Wait();
}
});
Console.ReadLine();
}
}
}
I am doing much the same thing but in VB.net.
WSJT-x runs on my "HamPC" and sends the udp packets to my "Programming" PC for decode.
Program skims the callsigns and looks up the stations Country/State via QRZ's XML service and plays a sound when a new state or country shows up on the band I am listening to.
I have yet to run 2 instances of my program on the "ProgrammingPC" but if I run into what you have I would add code so that the first running instance of my program will rebroadcast all of the packets exactly as received to another port for the second instance of my program to receive.
I found this thread looking for information on finding the Band information in the UDP packets transmitted by WJST-x. I've found and decoded the AudioFreq, TimeStamp and Signal Strength fields easily enough, now I'm scouring the data to locate the Band/Frequency which I need. Was easy in the first generation of my program which repeated read the all.txt file every 15 seconds at 01 16 31 and 41 seconds after the minute and determines which records are new (via simple line counting)
I have Googled high and low but cannot find a published structure of wjst-x's UDP packets - mainly offsets of the fields / how to decode them. I found the fields mentioned above by capturing the UDP packets looking at the contents byte by byte and comparing to the all.txt file for records written during the same transmissions.
The Band/Freq field should be the last one I need.
I believe my suggestion and retransmitting the packets intact to another port for the 2nd instance to receive on will work for you.
Program starts up unware if it is the 1st instance or not. It listen's on the primary port -- If data received on primary uses that port for receive and rebroadcasts the data as received to the 2nd port.
If no data was received on the 1st port it would switch and to listen on the 2nd port and not rebroadcast the data.
Perhaps a bandaid of a workaround but should work.
Best of luck! - 73 ne5B

Why is Ruby sockets server working with other Ruby sockets client but not a C# sockets client?

So I have two Ruby programs, they are a client and server sockets programs and they work together exchanging messages. But a C# client does not work. I give MCVE, first the ruby client.
#socketClient.rb
#With thanks to https://code.likeagirl.io/socket-programming-in-ruby-f714131336fd
require "socket"
while sum = $stdin.gets.chomp # Read lines from the socket
socket = TCPSocket.open("localhost", 3000)
#puts "Starting the Client..................."
socket.puts sum
while message = socket.gets # Read lines from the socket
puts message.chomp
end
socket.close # Close the socket
end
#puts "Closing the Client..................."
and the server
#simplestSocketServer.rb
#With thanks to https://code.likeagirl.io/socket-programming-in-ruby-f714131336fd
require "socket"
port = 3000
ipAddress = "127.0.0.1"
server = TCPServer.open(ipAddress, port) # Server would listen on port 3000
loop { # Servers run forever
puts "Starting the Server, accepting connections on port " + port.to_s + "..................."
client_connection = server.accept # Establish client connect connection
begin
clientText = client_connection.gets.chomp
puts clientText
resp = "Acknowledged"
client_connection.puts("#{clientText}" + "#{resp}") # Send the answer to the client
client_connection.puts("Closing the connection with #{client_connection}")
rescue Exception => getException
puts "#{getException}"
end
client_connection.close # Disconnect from the client
}
and the C# console program
using System;
using System.Net.Sockets;
using System.Text;
namespace SimplestCSharpRubySocketsClient
{
class Program
{
static void Main(string[] args)
{
try
{
string ipAddress = "127.0.0.1";
Int16 portNumber = 3000;
TcpClient _client; _client = new TcpClient();
_client.Connect(ipAddress, portNumber);
System.Console.WriteLine("we have connected, seemingly ...");
NetworkStream stream;
stream = _client.GetStream();
Byte[] sendBytes = Encoding.UTF8.GetBytes("some text");
System.Console.WriteLine("writing and flushing some bytes ...");
stream.Write(sendBytes, 0, sendBytes.Length);
stream.Flush();
Byte[] recvBytes = new byte[_client.ReceiveBufferSize];
System.Console.WriteLine("_client.ReceiveBufferSize = " + _client.ReceiveBufferSize); // <--- this prints 65536
System.Console.WriteLine("waiting to read bytes ...");
stream.Read(recvBytes, 0, recvBytes.Length); //<--- hangs here
System.Console.WriteLine("comething came back ...");
string result = Encoding.UTF8.GetString(recvBytes);
string result2 = result.Substring(0, result.LastIndexOf("\r\n"));
_client.Close();
_client.Dispose();
_client = null;
}
catch (Exception ex)
{
//TODO figure out a better error handler
throw ex;
}
}
}
}
The C# program connects and writes bytes but when looking to read bytes it just hangs.
And be aware I am running the C# console program in Visual Studio with admin rights. The two ruby programs run in their own separate Windows console windows.
Folding in some feedback, I added another line in the ruby server to output the clientText. And it prints nothing, suggesting the server is not fully receiving the bytes. Is there a termination signal that C# is required to send?
Thanks in advance.
The problem here is that the C# client does not send a newline at the end of the string, like the Ruby version does (socket.puts sends a string with a newline at the end).
If you change your sendBytes array to include a \n in the payload like this:
Byte[] sendBytes = Encoding.UTF8.GetBytes("some text\n");
you will see that it prints comething came back ... on the console.
The newline is required because of the following gets in the Ruby server:
clientText = client_connection.gets.chomp

How to Push data from C# to ZeroMQ and Pull from Node.JS or vice-versa?

Scenario:
I am trying to send a data (say String type) from C# сonsole application to Node.JS server through ZeroMQ.
Information:
Using clrzmq for c# and ZeroMQ libs for C# and Node.JS respectively
I am able to perform push-pull from Node.JS, also push - pull from C#.
So, one thing is confirmed that ZeroMQ - The Intelligent Transport Layer is installed on the machine (Windows 7 64-bit)
Issue:
I am not able to push data from C# Console app to Node.JS app (even tried vice-versa), both are on the same machine and on the same address i.e tcp://127.0.0.1:2222
Node.js code:
var zmq = require('zeromq.node');
var pull_socket = zmq.socket('pull');
pull_socket.connect('tcp://127.0.0.1:2222');
pull_socket.on('message', function (data) {
console.log('received data:\n');
console.log(data);
});
C# code:
namespace DataServiceEngine
{
class Program
{
static void Main(string[] args)
{
//clsApp App = new clsApp();
//App.appId = "001";
//App.name = "Back Office";
//Console.WriteLine("appId :" + App.appId + "\n");
//Console.WriteLine("name:" + App.name + "\n");
try
{
// ZMQ Context and client socket
using (var context = new Context(1))
{
using (Socket client = context.Socket(SocketType.PUSH))
{
client.Connect("tcp://127.0.0.1:2222");
string request = "Hello";
for (int requestNum = 0; requestNum < 10; requestNum++)
{
Console.WriteLine("Sending request {0}...", requestNum);
client.Send(request, Encoding.Unicode);
string reply = client.Recv(Encoding.Unicode);
Console.WriteLine("Received reply {0}: {1}", requestNum, reply);
}
}
}
}
catch (ZMQ.Exception exp)
{
Console.WriteLine(exp.Message);
}
}
}
}
Question: Can anyone tell me what may be the reason or where am I doing wrong?
I had the same issue (but I issued a communication Node.JS -> Node.JS). To solve the problem I used to do sendersocket.connect("tcp://"+host+":"+port); at the sender and receiversocket.bindSync("tcp://*:"+port); at the receiver.
Hope this fix your problem.

Send file from C# Server to AS3 AIR Clients using Sockets in a Local Network - with sample

I want to send a file from a C# server to a AS3 Flash Client. My C# server code for sending the file is something like this:
IPEndPoint ipEnd = new IPEndPoint(IPAddress.Any, 5656);
Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
sock.Bind(ipEnd);
sock.Listen(100);
//clientSock is the socket object of client, so we can use it now to transfer data to client
Socket clientSock = sock.Accept();
// This part gets the file and send the data in bytearray
byte[] fileData = File.ReadAllBytes("send/mypicture.jpg");
clientSock.Send(fileData);
Now I need a as3 client. I found this: http://flasharp.blogspot.pt/2010/03/socket-serverclient-chat.html and I constructed something like this:
public function Main():void {
...
socket.addEventListener(ProgressEvent.SOCKET_DATA, onResponse);
...
}
function onResponse(e:ProgressEvent):void {
var file:File;
var fs:FileStream;
var fileData:ByteArray = new ByteArray();
// Check if socket has data
if(socket.bytesAvailable > 0) {
while(socket.bytesAvailable) {
// read the socket data into the fileData
socket.readBytes(fileData,0,0);
}
}
file = File.documentsDirectory.resolvePath("teste.jpg");
fs = new FileStream();
fs.open(file, FileMode.WRITE);
// Writing the file
fs.writeBytes(fileData);
fs.close();
}
I've managed to send and receive a file, but it only saves up to 50kbs, anything bigger and you just gest a file with that size.
Any thoughts on how to transfer a file with any size?
I managed to solve this and updated this post with a sample.
UPDATED & SOLVED:
I wanted to send files from a C# server to AS3 Clients using sockets in a Local Network. I had some trouble finding out how to do it, but I managed to do so.
Server (C#):
1 - I create a TcpListener that listens for new clients with any IP in that network to the specified port number;
2 - When a new client connects I create a Thread to handle it;
3 - In that Thread I send the data I want to. In this case that data is divided in two parts, the first is a 4 bytearray that contains the size of the file I want to send, and the second is a bytearray of the file itself;
4 - After the data is sent I close that client connection;
Client (AS3):
1 - First of all I convert my bytearrays to LITTLE_ENDIAN, since AIR is by default BIG_ENDIAN and the data I get from the server is LITTLE_ENDIAN;
2 - Add the events to the socket connection and conect to the server;
3 - On the onResponse function I receive the socket packages to a bytearray;
4 - Save that bytearray into a file;
The last part on the client was the trickiest one, because it took me some time to figure out that AIR is BIG_ENDIAN by default, and how to read the packages.
So basically, what I do is, on the first package that comes in I read the first 4 bytes to a bytearray and then convert that to an int, which gives me my total file size. I use this to know when there are no more packages to receive and therefore finish the connection and save the file. The rest of the first package and subsequent packages are added to a bytearray that will store that file data itself. The workaround here is to start writing on the beggining the first time a package is received and then add the subsequent packages where the last one left off, i.e., first time I write from the 0 to 65321, second one I'll have to write from the 65321 to XXXX, and so on.
The file is being saved to the MyDocuments folder.
I'm unsure if this is the best method to do this, since I'm rather new to socket connection, however this works for me and I tested with files up to 165MB and it works. It supports multiple client connections and is pretty basic, but this is a starting point, not a finish line.
I hope this can help others as it helped me, since I did not find anything like it on the web (regarding file transfer not C# -> AS3 connection).
If someone wants to input some info or needs clarification on something, please feel free to ask.
Last but no least, sample can be downloaded here: http://sdrv.ms/W5mSs9 (Server in C# Express 2010 and Client in Flash Builder 4.6 with Flex SDK 4.6.0)
In case the sample in the link above ever dies out here is the
ActionScript 3 Source Code:
package
{
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.events.IOErrorEvent;
import flash.events.ProgressEvent;
import flash.events.SecurityErrorEvent;
import flash.filesystem.File;
import flash.filesystem.FileMode;
import flash.filesystem.FileStream;
import flash.net.Socket;
import flash.system.Security;
import flash.utils.ByteArray;
import flash.utils.Endian;
import flash.text.TextField;
public class FileTransferLocal extends Sprite
{
private var socket:Socket = new Socket();
private var file:File;
private var fs:FileStream = new FileStream();
private var fileData:ByteArray = new ByteArray();
private var fileSize:ByteArray = new ByteArray();
private var fileDataPosition:int = new int();
private var fileDataFlag:int = new int();
private var fileSizeFlag:int = new int();
private var fileSizeCounter:int = new int();
private var fileDataPreviousPosition:int = new int();
private var myText:TextField = new TextField();
public function FileTransferLocal()
{
try {Security.allowDomain("*");}catch (e) { };
// Convert bytearray to Little Endian
fileSize.endian = Endian.LITTLE_ENDIAN;
fileData.endian = Endian.LITTLE_ENDIAN;
socket.endian = Endian.LITTLE_ENDIAN;
fileSizeFlag = 0;
fileDataFlag = 0;
myText.width = 150;
myText.height = 150;
myText.x = 200;
myText.y = 200;
socket.addEventListener(Event.CONNECT, onConnect);
socket.addEventListener(Event.CLOSE, onClose);
socket.addEventListener(IOErrorEvent.IO_ERROR, onError);
socket.addEventListener(ProgressEvent.SOCKET_DATA, onResponse);
socket.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onSecError);
// Put the IP and port of the server
socket.connect("10.1.1.211", 5656);
}
private function onConnect(e:Event):void {
trace("onConnect\n");
}
private function onClose(e:Event):void {
trace("onClose");
socket.close();
}
private function onError(e:IOErrorEvent):void {
trace("IO Error: "+e);
}
private function onSecError(e:SecurityErrorEvent):void {
trace("Security Error: "+e);
}
private function onResponse(e:ProgressEvent):void {
if(!fileSizeFlag) {
socket.readBytes(fileSize, 0, 4);
fileSize.position = 0;
fileSizeFlag = 1;
fileSizeCounter = fileSize.readInt();
trace("fileSizeCounter -> " + fileSizeCounter);
}
trace("---- New package ----> " + socket.bytesAvailable);
if(fileSizeCounter > 0) {
fileSizeCounter -= socket.bytesAvailable;
if(fileDataPosition != 0) {
fileDataPreviousPosition += fileDataPosition;
}
if(fileData.length == 0) {
fileDataPreviousPosition = socket.bytesAvailable;
socket.readBytes(fileData, 0, socket.bytesAvailable);
} else {
fileDataPosition = socket.bytesAvailable;
socket.readBytes(fileData, fileDataPreviousPosition, socket.bytesAvailable);
}
}
// Saves the file
if(fileSizeCounter == 0) {
trace("File total size" + fileData.length);
file = File.documentsDirectory.resolvePath("test.mp3");
fs.open(file, FileMode.WRITE);
fs.writeBytes(fileData);
fs.close();
myText.text = "File successefully\nreceived!";
addChild(myText);
}
// Is still receiving packages
else {
myText.text = "Receiving file...";
addChild(myText);
}
}
}
}
In C# create a new Windows Application
add a
ListBox call it statusList
Label call it port
Label call it status
C# Source code in Sample Above:
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.Sockets;
using System.Threading;
using System.Net;
using System.IO;
using System.Reflection;
namespace ServerThread
{
public partial class ServerThread : Form
{
private TcpListener tcpListener;
private Thread listenThread;
public ServerThread()
{
InitializeComponent();
// Port number
int portNumber = 5656;
port.Text = portNumber.ToString();
// Create a TcpListener to cover all existent IP addresses with that port
this.tcpListener = new TcpListener(IPAddress.Any, portNumber);
// Create a Thread to listen to clients
this.listenThread = new Thread(new ThreadStart(ListenForClients));
this.listenThread.Start();
}
private void ListenForClients()
{
this.tcpListener.Start();
while (true)
{
// Blocks until a client has conected to the server
TcpClient client = this.tcpListener.AcceptTcpClient();
// Create a Thread to handle the conected client communication
Thread clientThread = new Thread(new ParameterizedThreadStart(HandleClientComm));
clientThread.Start(client);
}
}
private void HandleClientComm(object client)
{
// Receive data
TcpClient tcpClient = (TcpClient)client;
NetworkStream clientStream = tcpClient.GetStream();
while (true)
{
try
{
// Sending data
string filePath = "send/mysong.mp3"; // Your File Path;
byte[] fileData = File.ReadAllBytes(filePath); // The size of your file
byte[] fileSize = BitConverter.GetBytes(fileData.Length); // The size of yout file converted to a 4 byte array
byte[] clientData = new byte[fileSize.Length + fileData.Length]; // The total byte size of the data to be sent
fileSize.CopyTo(clientData, 0); // Copy to the file size byte array to the sending array (clientData) beginning the in the 0 index
fileData.CopyTo(clientData, 4); // Copy to the file data byte array to the sending array (clientData) beginning the in the 4 index
// Send the data to the client
clientStream.Write(clientData, 0, clientData.Length);
clientStream.Flush();
// Debug for the ListBox
if (statusList.InvokeRequired)
{
statusList.Invoke(new MethodInvoker(delegate {
statusList.Items.Add("Client IP: " + tcpClient.Client.RemoteEndPoint.ToString());
statusList.Items.Add("Client Data size: " + clientData.Length);
}));
}
}
catch
{
//
break;
}
if (statusList.InvokeRequired)
{
statusList.Invoke(new MethodInvoker(delegate
{
statusList.Items.Add("File successefully sent!");
}));
}
// Close the client
tcpClient.Close();
}
}
}
}

Categories

Resources