How to close read function on Com Port - c#

I'm trying to communicate on a com port on a single wire UART(Half Duplex). It's a C# Application with 8 bit MCU.
Here, Application is the master and MCU is a slave. On the MCU the RX is disabled while TX is sending.
The requirement is to make the com port disable the read function while I send data from the Application.
To do this, I tried to pull out from the buffer of RX after it transmits the number of bytes it transmits, but the MCU responds too fast and the last bytes of TX get in between with the response of the MCU.
Note: I can't change anything in the MCU
Here is my CODE:
public int serialRX()
{
int b;
if (serialPort.IsOpen && (serialPort.BytesToRead > 0))
{
try
{
b = serialPort.ReadByte();
}
catch (TimeoutException)
{
b = -1;
}
return b;
}
else
{
return -1;
}
}
public void serialTX(byte[] data)
{
if (serialPort.IsOpen)
{
serialPort.Write(data, 0, data.Length);
byte i = 0;
int read = -1;
while (i < data.Length)
{
while (read == -1)
{
read = serialRX();
}
read = -1;
i++;
}
}
}

Related

Sending multiple files from C# to C

I have a wpf gui that I want to upload files from and send to a C client .
I want to send 3 files and for some reason 1 of them is being sent and written (but it adds 8 nulls in the end and removes 4 of the first letters in the file)
and in the other two when I try to receive the size it says their size is 0
I've been stuck on this problem for a while now and i'm becoming depserate as i'm probably missing a small thing , if any of u could give a hand that'll mean a lot ! I really wanna know whats the problem in my code.
I have the files paths in an array and sending it in main like so
C# Main
IPEndPoint ipPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 5555);//switch the port
Socket listenSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
listenSocket.Bind(ipPoint);
listenSocket.Listen(1);
Socket clientSocket = listenSocket.Accept();
for (int i = 0; i < 1; i++)
{
SendFile(clientSocket, filePaths[i]);
}
clientSocket.Shutdown(SocketShutdown.Both);
clientSocket.Close();
SendFile(C# side)
public static void SendFile(Socket clientSocket, string filePath)
{
if (File.Exists(filePath))
{
FileInfo fi = new FileInfo(filePath);
long file_size = fi.Length;
byte[] preBuffer;
using (var memoryStream = new MemoryStream())
{
using (BinaryWriter writer = new BinaryWriter(memoryStream))
{
writer.Write(file_size);
}
preBuffer = memoryStream.ToArray();
byte[] fixedBuffer = new byte[4];
Array.Copy(preBuffer, 0, fixedBuffer, 0, 4);
Console.WriteLine(BitConverter.ToString(preBuffer));
Console.WriteLine(BitConverter.ToString(fixedBuffer)); //fixing the problem i had with the converting to array that it added 4 useless zeros.
clientSocket.Send(fixedBuffer); // sending size
}
byte[] data = new Byte[4096];
using (FileStream fs = new FileStream(filePath, FileMode.Open))
{
int actualRead;
do
{
actualRead = fs.Read(data, 0, data.Length);
clientSocket.Send(data);
file_size -= actualRead;
} while (file_size - filePath.Length > 0);
}
}
else
{
MessageBox.Show("File for the program is missing! lua/pcap/csv");
}
}
C Receive(built from 3 functions)
/*
============================================
General : function is responsible for receiving a length of data from the client
Parameters : sock - client socket to receive the data from
*buf - holds a pointer to the buffer that needs to update
bufsize - the length of the buffer
Return Value : returns TRUE when the data is read correctly
else, FALSE when there was a socket error or no bytes are received.
============================================
*/
bool recv_raw(SOCKET sock, void* buf, int bufsize)
{
unsigned char* pbuf = (unsigned char*)buf;
while (bufsize > 0) {
int num = recv(sock, pbuf, bufsize, 0);
if (num <= 0) { return false; }
pbuf += num;
bufsize -= num;
}
return true;
}
/*
===================================================
General : receives the length of the file and updates it
Parameters : sock - client socket to receive the data from
*filesize - holds a pointer to the size of the buffer that needs to update
filesize_len - the length of the file size pointer
Return Value : returns TRUE when the size is read correctly
else, FALSE when there was a socket error or no bytes are received.
===================================================
*/
bool recv_file_len(SOCKET sock, long* filesize)
{
if (!recv_raw(sock, filesize, sizeof(*filesize))) { return false; }
return true;
}
/*
================================================== =
General : writes to the lua file the data from the file
that was received in the socket
Parameters : sock - the socket between the client and server
*f - the file to write the data received to
Return Value : returns TRUE when everything was written to the file.
returns FALSE if there's no data received or detected a socket problem.
================================================== =
*/
bool write_data(SOCKET sock, FILE *f)
{
long filesize;//size of address
char buffer[BUFFER_SIZE];
if (!recv_file_len(sock, &filesize)) { return false; }
printf("file size (From C#) : %ld\n", filesize);
int n = recv_raw(sock, buffer, 8); // need to get the size of the name
if (filesize > 0)
{
do {
int num = min(filesize, BUFFER_SIZE);
if (!recv_raw(sock, buffer, num)) {
return false;
}
int offset = 0;
do
{
size_t written = fwrite(&buffer[offset], 1, num - offset, f);
if (written < 1) { return false; }
offset += written;
} while (offset < num);
filesize -= num;
} while (filesize > 0);
}
return true;
}
C Main
FILE* luafhandler = fopen("test.lua", "wb");//the new lua file
if (luafhandler == NULL)
{
fclose(luafhandler);
printf("GUI CONNECT lua file failed to open!\n");
}
FILE* pcapfhandler = fopen("test.pcap", "wb");//the new lua file
if (pcapfhandler == NULL)
{
fclose(pcapfhandler);
printf("GUI CONNECT pcap file failed to open!\n");
}
FILE* csvfhandler = fopen("AlgoTest.csv", "wb");//the new lua file
if (csvfhandler == NULL)
{
fclose(csvfhandler);
printf("GUI CONNECT csv file failed to open!\n");
}
else {
SOCKET sock1 = open_socket(5555, SERVER_IP);
bool check = write_data(sock1, luafhandler);
bool check1 = write_data(sock1, pcapfhandler);
bool check2 = write_data(sock1, csvfhandler);
fclose(luafhandler);
fclose(pcapfhandler);
fclose(csvfhandler);
}

Trasnfering file from C# WPF to C client

I am trying to pass a text file from a C# server based with wpf to a C client I made.
For some reason in the C part when I try to write into the file it says
An invalid parameter was passed to a function that considers invalid parameters fatal.
in the fwrite function.
What could be causing this?
I checked the file size sent and it was alright, both sides printed the same size and from the C# side it says it all been sent but the writing to file on the C side fails.
C# code for transfer:
public static void SendFile(Socket clientSocket, string fileName)
{
string folder = #"C:\Users\Roy\source\repos\GUI243\GUI243\";
string fullPath = folder + fileName;
FileInfo fi = new FileInfo(fullPath);
long file_size = fi.Length;
byte[] preBuffer;
using (var memoryStream = new MemoryStream())
{
using (BinaryWriter writer = new BinaryWriter(memoryStream))
{
writer.Write(file_size);
MessageBox.Show(file_size.ToString());
}
preBuffer = memoryStream.ToArray();
}
clientSocket.Send(preBuffer); // sending size
using (BinaryReader reader = new BinaryReader(new FileStream(fullPath, FileMode.Open)))
{
byte[] message = new Byte[4096];
int size_passed = 0;
do
{
reader.BaseStream.Seek(size_passed, SeekOrigin.Begin);
reader.Read(message, 0, 4096);
clientSocket.Send(message);
size_passed += 4096;
file_size -= message.Length;
} while (file_size > 0);
}
// clientSocket.SendFile(fullPath, preBuffer, null, TransmitFileOptions.UseDefaultWorkerThread);
MessageBox.Show("File has been sent!");
}
}
C client:
/*
============================================
General : function is responsible for receiving a length of data from the client
Parameters : sock - client socket to receive the data from
*buf - holds a pointer to the buffer that needs to update
bufsize - the length of the buffer
Return Value : returns TRUE when the data is read correctly
else, FALSE when there was a socket error or no bytes are received.
============================================
*/
bool recv_raw(SOCKET sock, void* buf, int bufsize)
{
unsigned char* pbuf = (unsigned char*)buf;
while (bufsize > 0) {
int num = recv(sock, pbuf, bufsize, 0);
if (num <= 0) { return false; }
pbuf += num;
bufsize -= num;
}
return true;
}
/*
===================================================
General : receives the length of the file and updates it
Parameters : sock - client socket to receive the data from
*filesize - holds a pointer to the size of the buffer that needs to update
filesize_len - the length of the file size pointer
Return Value : returns TRUE when the size is read correctly
else, FALSE when there was a socket error or no bytes are received.
===================================================
*/
bool recv_file_len(SOCKET sock, long* filesize)
{
if (!recv_raw(sock, filesize, sizeof(*filesize))) { return false; }
return true;
}
/*
===================================================
General : writes to the lua file the data from the file
that was received in the socket
Parameters : sock - the socket between the client and server
*f - the file to write the data received to
Return Value : returns TRUE when everything was written to the file.
returns FALSE if there's no data received or detected a socket problem.
===================================================
*/
bool receive_and_write_file(SOCKET sock, FILE *f)
{
long filesize;//size of address
if (!recv_file_len(sock, &filesize)) { return false; }
printf("file size (From C# client) : %ld\n", filesize);
if (filesize > 0)
{
char buffer[BUFFER_SIZE];
do {
int num = min(filesize, BUFFER_SIZE);
if (!recv_raw(sock, buffer, num)) {
return false;
}
int offset = 0;
do
{
size_t written = fwrite(&buffer[offset], 1, num - offset, f); // the fatal error
if (written < 1) { return false; }
offset += written;
} while (offset < num);
filesize -= num;
} while (filesize > 0);
}
return true;
}

C#: I have 100 clients to thread separately, what is the most effective way to send/receive data?

I'm doing a project with one Server and a Client for simulation purpose. The objective is to develop a single Server that can communicate with 100 clients at a same time using TCP and UDP. I am using TCPListener and UDPClient for both Server and Client. And I am using multi threading, creating an object class.
My code has 2 problems:
During the run, UDP packet gets lost, which freezes some of the threads.
The sending/receiving speed for UDP is immensely different (Thread 2 sent 2000 vs Thread 4 sent 900 etc)
Also, when I run 10 Threads, it will work perfectly fine. But when the number of threads increases, it will throw these problems.
I have the following bits of code ↓
Client (receiving function):
rpacket = new byte[1024];
//#0: UDP packet timeout
// is this necessary?? I could use while loop to measure waiting time.
net.tClient.Client.ReceiveTimeout = 1000;
net.client.Client.ReceiveTimeout = 1000;
//net.client.Client.SendTimeout = 2000;
// #1: message
_logIt(false, localThreadId, "started receivedata for threadid" + localThreadId);
// #2: number of received data recording
int nReceived = 0;
// #3: loop runs forever...
while (true)
{
// receiving data
bool recursion = false;
int recursionCount = 0;
int bytesReceived = 0;
// receiving data
bytesReceived = messageReceive(out recursion);
while (recursion == true)
{
// check if there are data 3 times
bytesReceived = messageReceive(out recursion);
recursionCount++;
if (recursionCount <= 3)
{
if (recursionCount == 1 && rIndex > 0)
{ rIndex--; }
// resend message
if (net.q[rIndex][1] == 0x00)
{
// sending data to PICS
// changed net.q[rIndex].Length - 1 to changed net.q[rIndex].Length - 2
try
{
int nBytesSend = net.client.Send(tempData, tempData.Length, net.ipEndPoint);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
// if 0x01, the protocl is TCP
else if (net.q[rIndex][1] == 0x01)
{
try {
int nBytesSend = net.tClient.Client.Send(tempData, tempData.Length, SocketFlags.None);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
}
else if (recursionCount == 4)
{
// hoot~ byebye
recursion = false;
Usage("hoot");
}
}
}
Client (sending function):
// if 0x00, the protocol is UDP
if (net.q[rIndex][1] == 0x00)
{
// sending data to PICS
// changed net.q[rIndex].Length - 1 to changed net.q[rIndex].Length - 2
int nBytesSend = net.client.Send(data, net.q[rIndex].Length - 2, net.ipEndPoint);
}
// if 0x01, the protocl is TCP
else if (net.q[rIndex][1] == 0x01)
{
int nBytesSend = net.tClient.Client.Send(data, net.q[rIndex].Length - 2, SocketFlags.None);
}
// June 1th, tempData is only used for failed messages
if (data.Length != 0)
{ tempData = data; }
Array.Resize(ref tempData, data.Length);
net.nSent++;
totalSent[localThreadId]++;
if (verbosity)
_logIt(false, localThreadId, "# of data sent: " + net.nSent);
// after sending, set the queue[][0] to 0x00
net.q[rIndex][0] = 0x00;
// setting queue[][1] is not neccessary...
rIndex++;
Message Receive(out recursion):
messageReceive(out bool audi)
{
int numBytes = 0;
audi = false;
// updated try and catch method, because there can be udp or tcp
try
{
rpacket = net.client.Receive(ref net.ipEndPoint);
numBytes = rpacket.Length;
}
catch (SocketException ex)
{
try
{
numBytes = net.tClient.Client.Receive(rpacket);
Array.Resize(ref rpacket, numBytes);
}
catch (Exception exc)
{
audi = true;
Console.WriteLine(exc.Message);
}
}
return numBytes;
}
Server side is same as the client.
FYI: there is a 2-D byte array called queue that stores all of the data that will be sent to the remote user. wIndex is a integer that is used for writing the reply data to the queue. rIndex is a integer that is used for reading the reply data from the queue and sends it to the remote user.
How can I fix my problems?
Warning Using multiple threads to send/receive with socket would lock the sockets and its I/O operation in your program.
When you are working with sockets it's better to work with async that sockets provide, like BeginRead and 'EndRead', because they make that the program will run over the same thread and it avoids the socket-client would get blocked. Also, don't use sleep into the socket-clients, they will block the socket.
Check this answer: C# High CPU usage on Listener thread, sleeping misses disconnect
In this answer i show how to use use the BeginRead and WriteRead.

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
}

How to determine that packet receive is a part of first packet using tcp in C#

i code socket application using blocing socket and use multithreading..my problem is i want to receive two large packet..as we know tcp must be split large data into multiple packet..this the scenario:
i send 6 mb text file and tcp split packet into 2 separate packet
at the same time i send 26 mb video file and tcp also split packet into 2 separate packet
at my application i recive first part of text file let say it 3 mb of 6 mb
and then i receive first part of video let say it 13 mb of 26 mb..
the question is how i know that first packet of text file and first packet of video file is a different data and should handle in different way..(different buffer maybe??)
sorry for my bad english..
thanks in advance..
this some part of my code
ns = client.GetStream();
while (isListen == true && client.Connected)
{
while (!ns.DataAvailable)
{
try
{
Thread.Sleep(1);
}
catch (Exception ex)
{
}
}
data = new byte[client.ReceiveBufferSize];
//client.Client.Receive(data);
int indx = ns.Read(data, 0, data.Length);
string message = Encoding.ASCII.GetString(data, 0, indx);
if (message == GetEnumDescription(TypeData.Disconnect))
{
isListen = false;
server.ClientKeluar = objClient;
if (ClientDisconnected != null)
{
ClientDisconnected(objClient);
}
thisThread.Abort();
Server.kumpulanThread.Remove(thisThread);
Server._serverConnections.Remove(this);
client.Close();
}
else if (message.Contains(GetEnumDescription(TypeData.GetFile)))
{
//jalankan proses pengambilan data
}
else if (message.Contains(GetEnumDescription(TypeData.ByteLength)))
{
string length = message.Substring(6, message.Length - 6);
int len = int.Parse(length);
expectedLength = client.ReceiveBufferSize = len;
data = new byte[len];
}
else if (message.Contains(GetEnumDescription(TypeData.Image)))
{
typeData = "Image";
dat1 = new byte[client.ReceiveBufferSize];
index = 0;
}
else if (message.Contains(GetEnumDescription(TypeData.Video)))
{
typeData = "Video";
dat2 = new byte[client.ReceiveBufferSize];
index = 0;
}
else
{
if (typeData == "Image")
{
expectedLength = expectedLength - message.Length;
if (expectedLength == 0)
{
Array.Copy(data, 0, dat1, index, message.Length);
if (ImageDelivered != null)
{
ImageDelivered(dat1);
}
}
else
{
Array.Copy(data, 0, dat1, index, message.Length);
index = message.Length;
}
}
else if (typeData == "Video")
{
expectedLength = expectedLength - message.Length;
if (expectedLength == 0)
{
Array.Copy(data, 0, dat2, index, message.Length);
if (VideoDelivered != null)
{
VideoDelivered(dat2);
}
}
else
{
Array.Copy(data, 0, dat2, index, message.Length);
index = message.Length;
}
}
else
{
expectedLength = expectedLength - message.Length;
if (expectedLength == 0)
{
dataToWrite = dataToWrite + message;
string text = dataToWrite;
if (MessageDelivered != null)
{
MessageDelivered(text);
}
dataToWrite = "";
}
else
{
dataToWrite += message;
}
}
}
}
may anyone give sample code so i can get inspiration to solve this problem?
TCP protocol take cares of making segments of files and later joining them. You will get complete data in receive.

Categories