I am trying to iterate each byte received over UDP and append that byte to a string (sbCardNo). The problem is the iteration for each byte is in the while loop, meaning a infinate loop (if I understand this correctly). How can I adapt the below code to add each byte to a string?
private void DoWork()
{
byte[] data = new byte[1024];
IPEndPoint ipep = new IPEndPoint(IPAddress.Any, 8888);
UdpClient newsock = new UdpClient(ipep);
IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
StringBuilder sbCardNo = new StringBuilder();
while (true)
{
data = newsock.Receive(ref sender);
sbCardNo.Append(data.GetValue(0));
FileStream fs = new FileStream(folderPath + "\\AuthService.txt",
FileMode.OpenOrCreate, FileAccess.Write);
StreamWriter m_streamwriter = new StreamWriter(fs);
m_streamwriter.BaseStream.Seek(0, SeekOrigin.End);
m_streamwriter.WriteLine(sbCardNo);
m_streamwriter.Flush();
m_streamwriter.Close();
}
}
The above code gives me the following -
2
252
25267
2526748
252674848
25267484870
2526748487069
25267484870693
I just need the last line - 25267484870693
Thanks
Create the file at the end of the while and write all the contents of the StringBuilder at once, and handle logic for possible excpetions
In this example its reading until the byte 'Z' is received, but is much better if the other side of this comunication sends a single String or that the first 2 bytes is the length of the bytes that will be sent
private void DoWork()
{
byte ch ;
byte[] data = new byte[1024];
IPEndPoint ipep = new IPEndPoint(IPAddress.Any, 8888);
UdpClient newsock = new UdpClient(ipep);
IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
StringBuilder sbCardNo = new StringBuilder();
while (true)
{
do
{
data = newsock.Receive(ref sender);
ch = data.GetValue(0)
sbCardNo.Append(ch);
} while (ch != 'Z') ;
using (StreamWriter m_streamwriter = new StreamWriter( folderPath + "\\AuthService.txt"))
{
m_streamwriter.WriteLine(sbCardNo.toString());
}
}
}
Related
I have a txt file that is 150kb. and i want to send it via socket programming and in a custom way:
I want to send first 136160 bytes through port x and 13840 bytes through another port (port y).
At the destination it also receives the first 136160 bytes but drops the next 13840 bytes.
In fact, I want this packet dropping to be dynamic so for each file we can individually specify how many bytes should be dropped.
I have the sender part of code and really in need of the codes in receiver part.
Thanks in advance for your answers and assistance
here is the normal codes of receiver which i use:
public void Listen(){
Socket SoListen = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint IPE = new IPEndPoint(IPAddress.Any, int.Parse(txtPort.Text));
SoListen.Bind(IPE);
SoListen.Listen(2);
Socket CGetFile = SoListen.Accept();
byte[] bfile = new byte[1024 * 1000000];
while (true)
{
int r = CGetFile.Receive(bfile);
if (r > 0)
{
this.Invoke(new Action(() =>
{
lblStatus.Text = "recieving";
SaveFileDialog SD = new SaveFileDialog();
if (SD.ShowDialog() == DialogResult.OK)
{
FileStream fs = new FileStream(SD.FileName, FileMode.Create);
fs.Write(bfile, 0, r);
fs.Flush();
lblStatus.Text = "recieved";
}
}));
Thread.CurrentThread.Abort();
}
}
}
I wrote a tcp listener to receive a sequence of images from single client , this is the code of server :
new Thread(() =>
{
while (true)
{
displayingFrame.Start(); // another thread to display images
Socket socket = listener.AcceptSocket();
TcpClient client = new TcpClient();
client.Client = socket;
Debug.WriteLine("Connection accepted.");
var childSocketThread = new Thread(() =>
{
NetworkStream ns = client.GetStream();
BinaryReader br = new BinaryReader(ns);
while (true)
{
using (MemoryStream ms = new MemoryStream())
{
int length = br.ReadInt32();
Debug.WriteLine("length : " + length);
byte[] buf = new byte[1024];
int totalReaded = 0;
int readed = 0;
while (totalReaded < length)
{
readed = br.Read(buf, 0, buf.Length);
ms.Write(buf, 0, readed);
totalReaded += readed;
}
byte[] frame = ms.ToArray();
this.frames.Enqueue(frame);
Debug.WriteLine("frame enqueued with length " + frame.Length);
}
}
});
childSocketThread.Start();
}
}).Start();
it receive frames very well but suddenly br.ReadInt32(); returns a very big length so br.Read(buf, 0, buf.Length); takes a very long time writing to memory stream and it writes a wrong data inside frame .
this is the client :
TcpClient client = new TcpClient();
client.Connect(new IPEndPoint(IPAddress.Loopback, 20000));
NetworkStream ns = client.GetStream();
BinaryWriter bw = new BinaryWriter(ns);
while ( true )
{
byte[] frame = Screenshot();
bw.Write(frame.Length);
Console.WriteLine("a frame length has flushed : " + frame.Length);
bw.Write(frame);
Console.WriteLine("a frame itself has flushed");
}
Console.ReadKey();
and here the debug info :
If you check the hex value you're getting - 1196314761 - you'll get 0x474E5089 and finally convert to ASCII you will get GNP\x89 which gives us the known magic value \x89PNG that is the marker of PNG file. You're actually reading the content of your screenshot as the length.
Make sure that you're code for reading the data does not read too much from the previous frame. I think you code for reading the data does not include the fact that you might get content of 2 frames in one .Read but then later you just don't care if you have too much data. You only check if it's not less than length.
I have a socket server and am trying to receive a string from the client.
The client is perfect and when I use this
Socket s = myList.AcceptSocket();
Console.WriteLine("Connection accepted from " + s.RemoteEndPoint);
byte[] b = new byte[100];
int k = s.Receive(b);
Console.WriteLine(k);
Console.WriteLine("Recieved...");
for (int i = 0; i < k; i++) {
Console.Write(Convert.ToChar(b[i]));
ASCIIEncoding asen = new ASCIIEncoding();
s.Send(asen.GetBytes("The string was recieved by the server."));
}
All is okay and I get my string in the console.
But how can I get now my receive into a string so I can use it in a switch case?
Like this:
string action = Convert.ToChar(b[i]);
Error:
The Name i isn't in the current context.
its the only Error Message i get.
This way no need set buffer size, it fits to response:
public static byte[] ReceiveAll(this Socket socket)
{
var buffer = new List<byte>();
while (socket.Available > 0)
{
var currByte = new Byte[1];
var byteCounter = socket.Receive(currByte, currByte.Length, SocketFlags.None);
if (byteCounter.Equals(1))
{
buffer.Add(currByte[0]);
}
}
return buffer.ToArray();
}
Assuming s is a Socket object on which you call receive, you get an byte[] back. To convert this back to a string, use the appropiate encoding, e.g.
string szReceived = Encoding.ASCII.GetString(b);
Edit: Since the buffer b is always 100 bytes, but the actual number of bytes received varies with each connection, one should use the return value of the Socket.Receive() call to only convert the actual number of received bytes.
byte[] b = new byte[100];
int k = s.Receive(b);
string szReceived = Encoding.ASCII.GetString(b,0,k);
Init socket
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPAddress ipAdd = System.Net.IPAddress.Parse(m_ip);
IPEndPoint remoteEP = new IPEndPoint(ipAdd, m_port);
Connect socket
socket.Connect(remoteEP);
Receive from socket
byte[] buffer = new byte[1024];
int iRx = socket.Receive(buffer);
char[] chars = new char[iRx];
System.Text.Decoder d = System.Text.Encoding.UTF8.GetDecoder();
int charLen = d.GetChars(buffer, 0, iRx, chars, 0);
System.String recv = new System.String(chars);
Send message
byte[] byData = System.Text.Encoding.ASCII.GetBytes("Message");
socket.Send(byData);
Close socket
socket.Disconnect(false);
socket.Close();
I have an ObservableCollection<MyClass> and I serialize its contents and send it using socket. Follow the code:
private const int Port = 3762;
private static SocketPermission permission = new SocketPermission(NetworkAccess.Accept, TransportType.Tcp, "", Port);
private static IPHostEntry ipEntry = Dns.GetHostEntry(string.Empty);
private static IPAddress ipAddress = ipEntry.AddressList[0];
private static IPEndPoint ipPoint = new IPEndPoint(ipAddress, Port);
Socket sTransmissao = new Socket(ipAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
using (var stream = new MemoryStream())
{
var binary = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
binary.Serialize(stream, TransmissaoPendencias);
byte[] bArray = new byte[stream.Length];
stream.Seek(0, SeekOrigin.Begin);
stream.Read(bArray, 0, (int)stream.Length);
sTransmissao.Connect(ipAddress, Port);
sTransmissao.Send(bArray);
}
But the byte length will change with the amount of items in my collection.
What is a viable solution to retrieving this information on the client side?
Thanks in advance.
You need to transmit the size before sending the array so that the other end knows how much to read.
I am trying to retrieve the byte that transferred by the server that has been programmed in c# as follow:
static void Main(String[] args){
Socket sListen = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPAddress IP = IPAddress.Parse("10.0.0.92");
IPEndPoint IPE = new IPEndPoint(IP, 4321);
sListen.Bind(IPE);
Console.WriteLine("Service is listening ...");
sListen.Listen(2);
while (true){
Socket clientSocket;
try{
clientSocket = sListen.Accept();
}
catch{
throw;
}
byte[] buffer = ReadImageFile("path to image");
clientSocket.Send(buffer, buffer.Length, SocketFlags.None);
Console.WriteLine("Send success!");
}
}
private static byte[] ReadImageFile(String img){
FileInfo fileinfo = new FileInfo(img);
byte[] buf = new byte[fileinfo.Length];
FileStream fs = new FileStream(img, FileMode.Open, FileAccess.Read);
fs.Read(buf, 0, buf.Length);
fs.Close();
//fileInfo.Delete ();
GC.ReRegisterForFinalize(fileinfo);
GC.ReRegisterForFinalize(fs);
return buf;
}
Above codes works fine when I write a client in the c# and run it in the pc. However I want to retrieve the bytes transferred by the server in the android device.
The android connected to the server successfully but it will not finish its job, basically it will not pass the ‘while loop in the bellow code’. I think there is something wrong with the byte length because it’s never get to ‘-1’.
Android java code (Client):
Socket socket = new Socket("ip", 4321);
InputStream is = socket.getInputStream();
byte[] buffer = new byte[1024];
int read = is.read(buffer);
while(read != -1){
read = is.read(buffer);
}
is.close();
socket.close();
I do appreciate any help in advance,
Thanks,
The client read() method will never return -1 until the server closes the connection. You're not doing that so it never happens.
I don't get the point of your Java code. The read(byte[]) method you are using writes 1024 bytes (or less) in the buffer again and again. You are overwriting your previous buffer content. You probably would like to write the downloaded data to somewhere, like an OutputStream. Example:
Socket socket = new Socket("ip", 4321);
InputStream is = socket.getInputStream();
OutputStream os = ...; // Where to save data, for example, new ByteArrayOutputStream();
copyStreams(is, os);
is.close();
socket.close();
public static void copyStreams(InputStream is, OutputStream os) throws IOException {
byte[] buffer = new byte[1024];
int numBytesRead;
for (;;) {
bytesRead = is.read(buffer);
if (bytesRead <= 0)
break;
os.write(buffer, 0, bytesRead);
}
}