C# ping with another mac - c#

I tried doing this but I receive many errors since I'm new to C# coding.
My actual purpose is I want to ping a static ip which is constantly receiving data from a temperature sensor. I want to see the data from my home and save the data.
using System;
using System.Net;
using System.Net.Sockets;
public class Pinger
{
public static int GetPingTime(string host)
{
int dwStart = 0, dwStop = 0;
// Create a raw socket.
Socket socket = new Socket(AddressFamily.InterNetwork,
SocketType.Raw, ProtocolType.Icmp);
// Get the server IPEndPoint, and convert it to an EndPoint.
IPHostEntry serverHE = Dns.GetHostByName(host);
IPEndPoint ipepServer = new IPEndPoint(serverHE.AddressList[0], 0);
EndPoint epServer = (ipepServer);
// Set the receiving endpoint to the client machine.
IPHostEntry fromHE = Dns.GetHostByName(Dns.GetHostName());
IPEndPoint ipEndPointFrom = new IPEndPoint(fromHE.AddressList[0], 0);
EndPoint EndPointFrom = (ipEndPointFrom);
// Construct the packet to send.
int PacketSize = 0;
IcmpPacket packet = new IcmpPacket();
for (int j = 0; j < 1; j++)
{
packet.Type = ICMP_ECHO;
packet.SubCode = 0;
packet.CheckSum = UInt16.Parse("0");
packet.Identifier = UInt16.Parse("45");
packet.SequenceNumber = UInt16.Parse("0");
int PingData = 32;
packet.Data = new Byte[PingData];
for (int i = 0; i < PingData; i++)
packet.Data[i] = (byte)'#';
PacketSize = PingData + 8;
Byte[] icmp_pkt_buffer = new Byte[PacketSize];
int index = 0;
index = Serialize(packet, icmp_pkt_buffer, PacketSize, PingData);
// Calculate the checksum for the packet.
double double_length = Convert.ToDouble(index);
double dtemp = Math.Ceiling(double_length / 2);
int cksum_buffer_length = Convert.ToInt32(dtemp);
UInt16[] cksum_buffer = new UInt16[cksum_buffer_length];
int icmp_header_buffer_index = 0;
for (int i = 0; i < cksum_buffer_length; i++)
{
cksum_buffer[i] = BitConverter.ToUInt16(icmp_pkt_buffer,
icmp_header_buffer_index);
icmp_header_buffer_index += 2;
}
UInt16 u_cksum = CheckSum(cksum_buffer, cksum_buffer_length);
packet.CheckSum = u_cksum;
// Now that we have the checksum, serialize the packet again.
byte[] sendbuf = new byte[PacketSize];
index = Serialize(packet, sendbuf, PacketSize, PingData);
// Start timing.
dwStart = System.Environment.TickCount;
socket.SendTo(sendbuf, PacketSize, 0, epServer);
// Receive the response, and then stop timing.
byte[] ReceiveBuffer = new byte[256];
socket.ReceiveFrom(ReceiveBuffer, 256, 0, ref EndPointFrom);
dwStop = System.Environment.TickCount - dwStart;
}
// Clean up and return the calculated ping time in seconds
socket.Close();
return (int)dwStop;
}
private static int Serialize(IcmpPacket packet, byte[] buffer,
int packetSize, int pingData)
{
// (Private method for serializing the packet omitted.)
}
private static UInt16 CheckSum(UInt16[] buffer, int size)
{
// (Private method for calculating the checksum omitted.)
}
public class PingTest
{
private static void Main()
{
int GetPingMS(string hostNameOrAddress);
System.Net.NetworkInformation.Ping ping = new System.Net.NetworkInformation.Ping();
return Convert.ToInt32(ping.SendAddress.RoundtripTime);
// How to call this function (IP Address).
MessageBox.Show ( GetPingMs("122.198.1.1"));
}
}

use This Sample because the Sample from Microsoft is not ready tu use...
http://www.codeplanet.eu/tutorials/csharp/4-tcp-ip-socket-programmierung-in-csharp.html?start=4
in this "german" Tutorial is the full code avaible for sending IP.
packet.Type = ICMP_ECHO; --> ICMP_ECHO must be set with a number (8) manual
{
private static int Serialize(IcmpPacket packet, byte[] buffer, int packetSize, int pingData)
{
// (Private method for serializing the packet omitted.)
}
private static UInt16 CheckSum(UInt16[] buffer, int size)
{
// (Private method for calculating the checksum omitted.)
}
}
<--mustbe create by your own
private static void Main()
{
int GetPingMS(string hostNameOrAddress);
System.Net.NetworkInformation.Ping ping = new System.Net.NetworkInformation.Ping();
return Convert.ToInt32(ping.SendAddress.RoundtripTime);
// How to call this function (IP Address).
MessageBox.Show ( GetPingMs("122.198.1.1"));
}
I think you never reach this Messagebox because you jump aut with
"return Convert.ToInt32(ping.SendAddress.RoundtripTime);"
set the meassagebox befor the return..

Related

What is the format of optval for MCAST_JOIN_SOURCE_GROUP setsockopt with IPv6 in Unix?

I'm trying to create a multicast testing tool for my local network. The only feature I don't yet have working is IPv6 SSM on Linux. I've used strace to try and debug and this is the error I'm receiving when I try to join the multicast group:
setsockopt(67, SOL_IPV6, MCAST_JOIN_SOURCE_GROUP, "\3\0\0\0\0\0\0\0\27\0\270\v\0\0\0\0\3778\0\0\0\0\0\0\0\0\0\0\207eC!"..., 264) = -1 EADDRNOTAVAIL (Cannot assign requested address)
Optval = 03000000000000001700B80B00000000FF38000000000000000000008765432100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001700000000000000FE8000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.
I am using interface 3, trying to connect to FF38::8765:4321 on port 3000 with FE80::1 as my source. This seems correct to me, any ideas what could be causing the error?
Edit: Here's my code to make the syscall:
[DllImport("libc", SetLastError = true)]
static extern int setsockopt(int sockfd, int level, int optname, void *optval, int size);
fixed(void* data = &joinData[0])
{
setsockopt((int)socket.Handle, 41, 46, data, joinData.Length);
}
and here's my code to populate optval:
byte[] joinBytes;
GroupSourceReqModel v6ssmJoin = new GroupSourceReqModel();
v6ssmJoin.gr_interface = (uint)selections.LocalIp.ScopeId;
SocketAddressIpv6InputModel mGroupIn = new SocketAddressIpv6InputModel
{
sin6_family = (ushort)selections.MulticastAddress.AddressFamily,
sin6_port = (ushort)selections.Port,
sin6_scope_id = 0
};
for (int i = 0; i < selections.MulticastAddress.GetAddressBytes().Length; i++)
{
mGroupIn.sin6_addr[i] = selections.MulticastAddress.GetAddressBytes()[i];
}
SocketAddressStorageModel groupSock = new SocketAddressStorageModel();
byte[] groupSockInData = ConvertToBytes(mGroupIn);
Console.WriteLine(Convert.ToHexString(groupSockInData));
byte* groupSockPointer = (byte*)&groupSock;
for (int i = 0; i < groupSockInData.Length; i++)
{
groupSockPointer[i] = groupSockInData[i]; // Now populate the groupSock object with the byte data of mGroupIn
}
v6ssmJoin.gsr_group = groupSock;
SocketAddressIpv6InputModel sGroupIn = new SocketAddressIpv6InputModel
{
sin6_family = (ushort)selections.SourceAddress.AddressFamily,
sin6_port = 0,
sin6_scope_id = 0
};
for (int i = 0; i < selections.SourceAddress.GetAddressBytes().Length; i++)
{
sGroupIn.sin6_addr[i] = selections.SourceAddress.GetAddressBytes()[i];
}
SocketAddressStorageModel sourceSock = new SocketAddressStorageModel
{
ss_family = (short)selections.SourceAddress.AddressFamily
};
byte[] sourceSockInData = ConvertToBytes(sGroupIn);
byte* sourceSockPointer = (byte*)&sourceSock;
for (int i = 0; i < sourceSockInData.Length; i++)
{
sourceSockPointer[i] = sourceSockInData[i];
}
v6ssmJoin.gsr_source = sourceSock;
joinBytes = ConvertToBytes(v6ssmJoin);
return joinBytes;
public static unsafe byte[] ConvertToBytes<T>(T value) where T : unmanaged
{
byte* pointer = (byte*)&value;
byte[] bytes = new byte[sizeof(T)];
for (int i = 0; i < sizeof(T); i++)
{
bytes[i] = pointer[i];
}
return bytes;
}
If it's relevant, I'm running on kernel version 5.4.0-122-generic.
Address family for IPv6 in Linux is 10, as seen in the kernel source code here which differs from the Windows value that C# uses. In addition, the port value is stored in big endian.

Byte array always return decimal not integer in c#

I try to create a simple calculator with client-server diagram in c# using System.Net.Socket. Everything working, but in server side, when I try to convert values receive from client, it's always convert the values to decimal, not integer but I try many time, still not solve.
Example, when client input a=5 and b=5 value, in a server side it's turn to 53 and 53.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;
namespace Server_Fix
{
class Program
{
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;
}
private static byte[] ReceiveVarData(Socket s)
{
int total = 0;
int recv;
byte[] datasize = new byte[4];
recv = s.Receive(datasize, 0, 4, 0);
int size = BitConverter.ToInt32(datasize,0);
int dataleft = size;
byte[] data = new byte[size];
while (total < size)
{
recv = s.Receive(data, total, dataleft, 0);
if (recv == 0)
{
data = Encoding.ASCII.GetBytes("exit ");
break;
}
total += recv;
dataleft -= recv;
}
return data;
}
public static void Main()
{
byte[] data = new byte[1024];
byte[] data1 = new byte[1024];
byte[] data2 = new byte[1024];
byte[] data3 = 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);
string welcome = "CALCULATOR CLIENT-SERVER DIAGRAM!";
data = Encoding.ASCII.GetBytes(welcome);
int sent = SendVarData(client, data);
string phepToan;
int result=0;
int a = 0, b = 0;
while(true)
{
sent = SendVarData(client, Encoding.ASCII.GetBytes("Nhap vao so a: "));
data1 = ReceiveVarData(client);
//Console.WriteLine("Client: " + Encoding.ASCII.GetString(data));
sent = SendVarData(client, Encoding.ASCII.GetBytes("Nhap vao so b: "));
data2 = ReceiveVarData(client);
//b = Convert.ToInt32(data2);
sent = SendVarData(client, Encoding.ASCII.GetBytes("Cho biet phep tinh can dung la | + | - | * | / |: "));
data3 = ReceiveVarData(client);
phepToan = Encoding.ASCII.GetString(data3);
//a = Convert.ToString(Encoding.ASCII.GetString(data1));
if (phepToan=="+")
{
foreach (byte byteValue in data1)
{
a = Convert.ToChar(byteValue); //It's always turn to Decimal values
}
foreach (byte byteValue in data2)
{
b = Convert.ToChar(byteValue); //It's always turn to Decimal values
}
result = a + b;
sent = SendVarData(client, Encoding.ASCII.GetBytes("Ket qua phep tinh: "+Convert.ToString(result)));
}
if (phepToan == "-")
{
}
if (phepToan == "*")
{
}
if (phepToan == "/")
{
}
}
Console.WriteLine("Disconnected from {0}", newclient.Address);
client.Close();
newsock.Close();
Console.ReadLine();
}
}
}
================================================================
Code of client side
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;
namespace Client_Fix
{
class Program
{
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;
}
private static byte[] ReceiveVarData(Socket s)
{
int total = 0;
int recv;
byte[] datasize = new byte[4];
recv = s.Receive(datasize, 0, 4, 0);
int size = BitConverter.ToInt32(datasize,0);
int dataleft = size;
byte[] data = new byte[size];
while (total < size)
{
recv = s.Receive(data, total, dataleft, 0);
if (recv == 0)
{
data = Encoding.ASCII.GetBytes("exit ");
break;
}
total += recv;
dataleft -= recv;
}
return data;
}
public static void Main()
{
byte[] data = new byte[1024];
int sent;
IPEndPoint ipep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 9050);
Socket server = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
try
{
server.Connect(ipep);
}
catch (SocketException e)
{
Console.WriteLine("Unable to connect to server.");
Console.WriteLine(e.ToString());
return;
}
string input;
data = ReceiveVarData(server);
string stringData = Encoding.ASCII.GetString(data);
Console.WriteLine(stringData);
while (true)
{
data = ReceiveVarData(server);
Console.Write("Server: " + Encoding.ASCII.GetString(data));
Console.WriteLine("You: " + input);
sent = SendVarData(server, Encoding.ASCII.GetBytes(input));
data = ReceiveVarData(server);
Console.Write("Server: " + Encoding.ASCII.GetString(data));
input = Console.ReadLine();
//Console.SetCursorPosition(0, Console.CursorTop - 1);
Console.WriteLine("You: " + input);
sent = SendVarData(server, Encoding.ASCII.GetBytes(input));
data = ReceiveVarData(server);
Console.Write("Server: " + Encoding.ASCII.GetString(data));
input = Console.ReadLine();
//Console.SetCursorPosition(0, Console.CursorTop - 1);
Console.WriteLine("You: " + input);
sent = SendVarData(server, Encoding.ASCII.GetBytes(input));
data = ReceiveVarData(server);
Console.WriteLine("Server: " + Encoding.ASCII.GetString(data));
}
Console.WriteLine("Disconnecting from server...");
server.Shutdown(SocketShutdown.Both);
server.Close();
Console.ReadLine();
}
}
}
Let's assume byteValue is 53, the codepoint of the character '5'.
Then
Convert.ToChar(byteValue)
will give 53. That's fine, chars in C# have a numeric value, which is their ordinal in the character table.
One way to solve your problem would be this:
var a = int.Parse(ASCIIEncoding.ASCII.GetString(new byte[] { bytevalue }));
Or, again with some speculation, more likely:
var a = int.Parse(ASCIIEncoding.ASCII.GetString(data1));
Here, the numeric representation of the character digit '5' as it comes over the wire (as 53), will be looked up in the ASCII table, giving "5", and then parsed into the desired integer.
But it does not fix the root problems with the whole code, which would require a more thorough planning of how bits of information are to be encoded, transported, and subsequently decoded in a reliable fashion.

Sending multiple files on different threads Sockets c#

I am working on a software that transfers multiple files between different computers but i am faced with the problem of concurrency. When both threads start sending using Task.Run() the bytes mumble up on the receiving side i.e the data clashes together. I have tried locking every possible part of my code that could cause the error all to no avail. This is part of my code.
//code to transfer asynchronously
public void StartTransferAsync(Socket socket)
{
Task.Factory.StartNew(() =>
{
lock (this)
{
uploader = new Uploader(this, socket);
uploader.Upload();
}
});
}
//code to receive the asynchronous files coming in
public byte[] DownloadData()
{
int total = 0;
int recv = 0;
int size = 0;
int dataleft = 0;
byte[] data;
byte[] dataSize = new byte[4];
recv = socket.Receive(dataSize, 0, 4, 0);
size = BitConverter.ToInt32(dataSize, 0);
Console.WriteLine($"Size received: {size}");
if (size > 100038)
{
Console.WriteLine("Shii here");
}
dataleft = size;
data = new byte[size];
while (total < size)
{
recv = socket.Receive(data, total, dataleft, 0);
total += recv;
dataleft -= recv;
}
return data;
}
Please help i really need this.

DMX USB Pro(FTDI) works very sporadically

I've been trying to write a C# application that send data to a stage light using the Enttec DMX USB Pro box. There are provided C# wrappers that I'm using and I've gotten the light to respond as expected but it very rarely works. I seem to have to switch between using from off the shelf application to "reset" the connection a few times before I can get it to start responding to my writes.
My DMX Code is
class DmxDriver
{
const int DMX_PACKET_SIZE = 513;
private bool connected;
private FTDI device;
private int startAddr;
private byte[] packet;
public DmxDriver(int baseDmxAddr)
{
startAddr = baseDmxAddr;
device = new FTDI();
FTDI.FT_STATUS result = device.OpenByIndex(0);
if (result == FTDI.FT_STATUS.FT_OK)
{
connected = true;
Console.WriteLine("DMX connected");
}
else
{
connected = false;
Console.WriteLine("DMX CONNECTION FAILED");
}
packet = new byte[DMX_PACKET_SIZE];
for (int i = 0; i < DMX_PACKET_SIZE; i++)
{
packet[i] = 0;
}
}
~DmxDriver()
{
device.Close();
}
public bool deviceConnected()
{
return connected;
}
public void sendData()
{
if (packet.Length != 513)
{
return;
}
uint written = 0;
FTDI.FT_STATUS result;
byte[] header = new byte[4];
header[0] = 0x7E; //start code
header[1] = 6; //DMX TX
header[2] = 255 & 0xFF; //pack length logical and with max packet size
header[3] = 255 >> 8; //packet length shifted by byte length? DMX standard idk
result = device.Write(header, 4, ref written);//send dmx header
Console.WriteLine(result);
Console.WriteLine(written);
result = device.Write(packet, 513, ref written);//send data array
Console.WriteLine(result);
Console.WriteLine(written);
byte[] endcode = new byte[1];
endcode[0] = 0xE7;
device.Write(endcode, 1, ref written);//send dmx end code
}

C# UDP going slower then TCP

I'm trying to stream a video feed form the Xbox Kinect from a client to a server. I got it working with TCP but I could only get about 5 fps so now I'm trying it with UDP. UDP should be faster because of how the protocol works but it seems to be slower. Here is my post about the TCP (http://stackoverflow.com/questions/9627242/c-sharp-streaming-video-over-networkstream-tcpclient)
I can send this all the data I want over my LAN but I start losing a lot of packets if I push them out too fast. That is why I am using the Thread.Sleep(20); Increasing the chuck size speeds it up a lot but I'm at my max for sending over my LAN and if I understand correctly the max chunk size for sending over the internet is about 1500 bytes. If I only sent 1500 bytes at a time this would go really slow. I must be doing something wrong.
Here is the code.
private const int constChunkSize = 38400;
protected UdpClient udpObject;
private void HandleComm()
{
byte[] fullMessage = new byte[1228800];
byte[] byteReceived;
int currentIndex = 0;
IPEndPoint remoteIPEndPoint = new IPEndPoint(ip, port);
while (true)
{
byteReceived = udpObject.Receive(ref remoteIPEndPoint);
if (currentIndex + byteReceived.Length > 1228800)
{
int wtf = 0;
}
Array.Copy(byteReceived, 0, fullMessage, currentIndex, byteReceived.Length);
currentIndex += byteReceived.Length;
//Console.WriteLine("Recieved: " + currentIndex);
if (currentIndex == 1228800)
{
if (OnDataReceived != null)
{
FrameReceivedArgs args = new FrameReceivedArgs();
args.frame = new byte[fullMessage.Length];
fullMessage.CopyTo(args.frame, 0);
OnDataReceived(this, args);
}
currentIndex = 0;
Console.WriteLine("Done receiving" + DateTime.Now.Ticks);
}
}
}
public void sendData(byte[] data)
{
sending = true;
sendThread = new Thread(sendDataThread);
sendThread.Priority = ThreadPriority.Highest;
sendThread.Start(data);
}
private void sendDataThread(object tempData)
{
byte[] data = (byte[]) tempData;
int totalBytes = data.Length;
int currentBytes = 0;
int bufferLength = constChunkSize;
byte[] sendBytes = new byte[constChunkSize];
while (currentBytes < totalBytes)
{
if (totalBytes - currentBytes < constChunkSize)
bufferLength = totalBytes - currentBytes;
Array.Copy(data, currentBytes, sendBytes, 0, bufferLength);
currentBytes += bufferLength;
udpObject.BeginSend(sendBytes, bufferLength, new AsyncCallback(sendingData), udpObject);
Thread.Sleep(20);
//Console.WriteLine("Sent: " + currentBytes);
}
Console.WriteLine("done sending" + DateTime.Now.Ticks);
sending = false;
}
private void sendingData(IAsyncResult ar)
{
udpObject.EndSend(ar);
}

Categories