NAudio AsioOut + Sockets - c#

I'm newbie in audio programming and in sockets programming. I'm trying to send guitar signal over a network using NAudio AsioOut class and Sockets.
Here's source code of Receiver and Sender.
It seems like the receiver really gets the bytes array from sender, but all what I hear is white noise.
Receiver source code
using System;
using System.Net;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Threading;
using NAudio.Utils;
using NAudio.Wave;
using NAudio.Wave.SampleProviders;
namespace Reciever
{
internal class Program
{
private static Socket Listener;
private static Socket Accepter;
private static AsioOut Output;
private static BufferedWaveProvider OutputBuffer;
[STAThread]
private static void Main(string[] args)
{
IPHostEntry ipHostEntry = Dns.GetHostEntry("192.168.1.4");
IPAddress ipAddr = ipHostEntry.AddressList[2];
IPEndPoint ipEndPoint = new IPEndPoint(ipAddr, 7777);
Listener = new Socket(ipAddr.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
Console.WriteLine("Слушатель готов по адресу:{0} ", ipEndPoint);
Listener.Bind(ipEndPoint);
Listener.Listen(10);
Accepter = Listener.Accept();
Console.WriteLine("Клиент с адресом {0} подключен", Accepter.RemoteEndPoint);
Output = new AsioOut();
Output.ShowControlPanel();
Console.Read();
OutputBuffer = new BufferedWaveProvider(WaveFormat.CreateIeeeFloatWaveFormat(44100, 2));
Output.Init(OutputBuffer);
Thread playing = new Thread(new ThreadStart(Output.Play));
Thread listening = new Thread(new ThreadStart(Listening));
playing.Start();
listening.Start();
}
public static void Listening()
{
while (true)
{
byte[] buffer = new byte[65538];
int ReceivedData = Accepter.Receive(buffer);
OutputBuffer.AddSamples(buffer, 0, ReceivedData);
}
}
}
}
Sender source code
using System;
using System.Net;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using NAudio.Wave;
namespace Sender
{
class Program
{
private static Socket sck;
[STAThread]
static void Main(string[] args)
{
AsioOut asioout = new AsioOut();
IPHostEntry ipHostEntry = Dns.GetHostEntry("192.168.1.2");
IPAddress ipAddr = ipHostEntry.AddressList[1];
IPEndPoint ipEndPoint = new IPEndPoint(ipAddr, 7777);
sck = new Socket(ipEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
BufferedWaveProvider buffer = new BufferedWaveProvider(WaveFormat.CreateIeeeFloatWaveFormat(44100,2));
sck.Bind(ipEndPoint);
try
{
sck.Connect("192.168.1.4", 7777);
}
catch (Exception ex)
{
Console.WriteLine("Соединие не установлено");
Console.Read();
return;
}
Console.WriteLine("Соединение установлено");
asioout.InitRecordAndPlayback(buffer, 2, 44100);
asioout.AudioAvailable += new EventHandler<AsioAudioAvailableEventArgs>(asioout_AudioAvailable);
asioout.Play();
Console.Read();
}
private static void asioout_AudioAvailable(object sender, AsioAudioAvailableEventArgs e)
{
var samples = e.GetAsInterleavedSamples();
byte[] OutputBuffer = new byte[e.SamplesPerBuffer*4];
byte[] SendingBuffer = new byte[e.SamplesPerBuffer*4];
Console.WriteLine(e.SamplesPerBuffer*4);
for (int i = 0; i < e.InputBuffers.Length; i++)
{
Marshal.Copy(e.InputBuffers[i], OutputBuffer, 0, e.SamplesPerBuffer*4);
Buffer.BlockCopy(samples, 0, SendingBuffer, 0, e.SamplesPerBuffer*4);
Marshal.Copy(OutputBuffer, 0, e.OutputBuffers[i], e.SamplesPerBuffer * 4);
}
sck.Send(SendingBuffer);
e.WrittenToOutputBuffers = true;
}
}
}
UPD.1 (07.10.2015): Sender code and Receiver code are updated. Now I can hear the guitar signal from receiver, but it sounds very distorted. What I do wrong?
P.S. I'm using M-Audio Fast Track USB sound card on my desktop PC. The signal goes from that one to my laptop with ASIO4ALL driver over the network.

Your receiver assumes that the incoming audio is 16 bit, but with ASIO, it could easily be 24 or 32 bit. In fact, your sending code seems to assume 32 bit. So start by trying to use an IEEE float WaveFormat on the receiving end

Related

Unity3d client - Python server real-time communication

I am trying to create a client server app using Unity3D and python. I am trying to send big amount of data from server to client in real time. In order to do that i divided the data to be received in smaller bulks so the serialization/deserialization to be faster so the update of unity objects based on data to be faster as well.
I approached the problem like this:
I open 5 sockets and each try to handle the request based on an identifier
On client I use parallel.foreach for sending the five identifiers and receiving then in parallel.
The issue is that client.Receive blocks when there is no data to receive. I tried to set a timeout but it is not really helpful.
Also the length of data is variable for the packages received.
Python server implementation is similar to this but it is not that relevant i assume tho: Is it possible to run multiple asyncio in the same time in python?
Socket class:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Net.Sockets;
using System;
using System.IO;
public class SocketConnector
{
public string ip = "127.0.0.1";
public int port = 60000;
private Socket client;
[SerializeField]
private int dataOut;
private byte[] dataIn; //debugging
public SocketConnector() { }
public void establishConnection(int port)
{
client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
client.Connect(ip, port);
}
public byte[] ServerRequest(int dataOut)
{
//print("request");
this.dataOut = dataOut; //debugging
this.dataIn = SendAndReceive(dataOut); //debugging
return this.dataIn;
}
private byte[] SendAndReceive(int dataOut)
{
byte[] z = new byte[1024 * 1024 * 1500];
try
{
byte[] intBytes = BitConverter.GetBytes(dataOut);
client.Send(intBytes);
client.ReceiveTimeout = 2000;
//allocate and receive bytes
byte[] bytes = new byte[1024 * 1024 * 1500];
Array.Clear(bytes, 0, bytes.Length);
int lenght = 1, byteIndex = 0;
lenght = client.Receive(bytes); // is blocking here cos no data is received sometime
Buffer.BlockCopy(bytes, 0, z, byteIndex, lenght);
byteIndex += lenght;
Array.Resize(ref z, byteIndex);
Debug.Log("request received");
}
catch (Exception e)
{
Debug.Log("smth happened");
}
client.Close();
return z;
}
}
Main class:
...
void Start()
{
ThreadCompoennt threadComponent = new ThreadComponent(socketConnector, this, featureMapCreator);
threadComponent.init();
}
...
Thread component:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Threading;
using System.Linq;
using System.Threading.Tasks;
using MessagePack;
using System;
public class ThreadComponent
{
Thread thread;
SocketConnector socketConnector;
Main main;
Dictionary<string, Dictionary<string, ushort[][]>> feature;
StructHelper structHelper;
byte[] z;
public ThreadComponent(SocketConnector socketConnector, Main main, FeatureMapCreator featureMapCreator)
{
this.featureMapCreator = featureMapCreator;
this.socketConnector = socketConnector;
this.main = main;
}
public void init()
{
thread = new System.Threading.Thread(doLogic);
thread.IsBackground = true;
thread.Start();
}
void doLogic()
{
List<int> integerList = Enumerable.Range(1, 5).ToList();
while (true)
{
Thread.Sleep(2000);
Parallel.ForEach(integerList, i =>
{
socketConnector.establishConnection(60000 + i);
doLogicGetData(i, socketConnector);
});
}
}
void doLogicGetData(int batchIdentifier, SocketConnector socketConnector)
{
z = socketConnector.ServerRequest(batchIdentifier);
if (z.Length != 0)
{
this.feature = MessagePackSerializer.Deserialize<Dictionary<string, Dictionary<string,ushort[][]>>>(z);
..... do update based on batch identifier
}
}

C# - Sockets not receiving all bytes

I have been struggling to fix my mistake. My client/server seems to work fine when on the same machine. When the code is executed on a different PC, for some reason only part of the bytes are reaching the server. I cannot seem to get the bytes to go through to matter how much I try. It seems the cutoff point is 367 bytes and it does not want to transfer anymore. If anyone knows what I am doing wrong, a solution would be much appreciated.
Thanks in advance!
Server:
using System;
using System.Data.SQLite;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Threading;
namespace DMAssist
{
// State object for reading client data asynchronously
public class StateObject
{
// Client socket.
public Socket workSocket = null;
// Size of receive buffer.
public const int BufferSize = 1024;
// Receive buffer.
public byte[] buffer = new byte[BufferSize];
// Received data string.
public StringBuilder sb = new StringBuilder();
// Current URL string
}
public class asyncserver
{
public asyncserver()
{
}
// Thread signal.
public static ManualResetEvent allDone = new ManualResetEvent(false);
public static string GetLocalIPAddress()
{
var host = Dns.GetHostEntry(Dns.GetHostName());
foreach (var ip in host.AddressList)
{
if (ip.AddressFamily == AddressFamily.InterNetwork)
{
return ip.ToString();
}
}
throw new Exception("Local IP Address Not Found!");
}
public void StartListening()
{
// Data buffer for incoming data.
byte[] bytes = new Byte[1024];
// Establish the local endpoint for the socket.
// The DNS name of the computer
// running the listener is "host.contoso.com".
IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName());
IPAddress ipAddress = ipHostInfo.AddressList[0];
IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 25599);
// Create a TCP/IP socket.
Socket listener = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
// Bind the socket to the local endpoint and listen for incoming connections.
try
{
listener.Bind(localEndPoint);
listener.Listen(100);
while (true)
{
// Set the event to nonsignaled state.
allDone.Reset();
// Start an asynchronous socket to listen for connections.
Console.WriteLine("Waiting for a connection...");
listener.BeginAccept(
new AsyncCallback(AcceptCallback),
listener);
// Wait until a connection is made before continuing.
allDone.WaitOne();
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
Console.WriteLine("\nPress ENTER to continue...");
Console.Read();
}
public void AcceptCallback(IAsyncResult ar)
{
// Signal the main thread to continue.
allDone.Set();
// Get the socket that handles the client request.
Socket listener = (Socket)ar.AsyncState;
Socket handler = listener.EndAccept(ar);
// Create the state object.
StateObject state = new StateObject();
state.workSocket = handler;
handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(ReadCallback), state);
}
public byte[] ObjectToByteArray(object obj)
{
if (obj == null)
return null;
BinaryFormatter bf = new BinaryFormatter();
MemoryStream ms = new MemoryStream();
bf.Serialize(ms, obj);
return ms.ToArray();
}
private Object ByteArrayToObject(byte[] arrBytes)
{
MemoryStream memStream = new MemoryStream();
BinaryFormatter binForm = new BinaryFormatter();
memStream.Write(arrBytes, 0, arrBytes.Length);
memStream.Seek(0, SeekOrigin.Begin);
Object obj = (Object)binForm.Deserialize(memStream);
return obj;
}
public void ReadCallback(IAsyncResult ar)
{
String content = String.Empty;
String connectedAddress = String.Empty;
// Retrieve the state object and the handler socket
// from the asynchronous state object.
StateObject state = (StateObject)ar.AsyncState;
Socket handler = state.workSocket;
IPEndPoint remoteIpEndPoint = handler.RemoteEndPoint as IPEndPoint;
connectedAddress = remoteIpEndPoint.Address.ToString();
// Read data from the client socket.
int bytesRead = handler.EndReceive(ar);
if (bytesRead > 0)
{
Console.WriteLine("Bytes read: " + bytesRead);
// There might be more data, so store the data received so far.
state.sb.Append(Encoding.ASCII.GetString(
state.buffer, 0, bytesRead));
object rawbytes = ByteArrayToObject(state.buffer);
netObject recvobject = (netObject)rawbytes;
Send(handler, (object)recvobject);
}
}
private void Send(Socket handler, object data)
{
// Convert the string data to byte data using ASCII encoding.
byte[] byteData = ObjectToByteArray(data);
// Begin sending the data to the remote device.
handler.BeginSend(byteData, 0, byteData.Length, 0,
new AsyncCallback(SendCallback), handler);
}
private static void SendCallback(IAsyncResult ar)
{
try
{
// Retrieve the socket from the state object.
Socket handler = (Socket)ar.AsyncState;
// Complete sending the data to the remote device.
int bytesSent = handler.EndSend(ar);
Console.WriteLine("Sent {0} bytes to client.", bytesSent);
handler.Shutdown(SocketShutdown.Both);
handler.Close();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
}
}
Client:
using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Text;
using System.Windows.Forms;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
using System.Collections;
namespace DMAssist
{
public class asyncsclient {
public asyncsclient()
{
}
public byte[] ObjectToByteArray(object obj)
{
if (obj == null)
return null;
BinaryFormatter bf = new BinaryFormatter();
MemoryStream ms = new MemoryStream();
bf.Serialize(ms, obj);
return ms.ToArray();
}
private Object ByteArrayToObject(byte[] arrBytes)
{
MemoryStream memStream = new MemoryStream();
BinaryFormatter binForm = new BinaryFormatter();
memStream.Write(arrBytes, 0, arrBytes.Length);
memStream.Seek(0, SeekOrigin.Begin);
Object obj = (Object)binForm.Deserialize(memStream);
return obj;
}
static byte[] GetBytes(string str)
{
byte[] bytes = new byte[str.Length * sizeof(char)];
System.Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length);
return bytes;
}
static string GetString(byte[] bytes)
{
char[] chars = new char[bytes.Length / sizeof(char)];
System.Buffer.BlockCopy(bytes, 0, chars, 0, bytes.Length);
return new string(chars);
}
public object sendObject(object outgoingObject, bool expectRecieve)
{
try
{
Socket soc = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPAddress ip = IPAddress.Parse("x.x.x.x");
IPEndPoint remoteEP = new IPEndPoint(ip, 25599);
soc.Connect(remoteEP);
byte[] byData = ObjectToByteArray(outgoingObject);
//Console.WriteLine("Array length:" + byData.Length);
soc.Send(byData);
if (expectRecieve)
{
byte[] buffer = new byte[1024];
int iRx = soc.Receive(buffer);
object rawbytes = ByteArrayToObject(buffer);
netObject recvobject = (netObject)rawbytes;
Console.WriteLine("Writing stopped");
soc.Close();
soc.Dispose();
return recvobject;
}
else
{
soc.Close();
soc.Dispose();
return "";
}
}
catch (Exception)
{
MessageBox.Show("Server unreachable. Make sure server is broadcasting on port 25599 successfully.", "DMAssist Error 0xC1");
}
return null;
}
}
}
There is a big difference between UDP sockets and TCP sockets.
What you are trying would work better with UDP because this protocol is more packet oriented. This means that if a server sends a certain number of bytes, the client 'might' receive the same certain number of bytes or receive nothing at all.
For TCP it is different because it is a streaming protocol which means bytes are just sent sequentially anyway the server sees fit. Usually it will try to fill up to the mtu and when you receive you will very likely receive the data in multiple chunks that you have to append yourself. TCP is a also connection oriented and reliable. Bytes are acked from the client to the server and vice versa, and retransmitted if an ack is not received in due time. This means even that packets can at the TCP level be received out of order. TCP will fit them together. You at the application level will receive everything in order.
The advice you got so far is correct, you have to keep calling receive. And this until there is nothing to receive anymore. And how do you know that there is nothing to receive anymore ? Usually that is detected by receiving a TCP message in receive with 0 length. This means that the peer has closed its end of the socket and will not send anymore. This in turn means that you can close your end of the socket.
This is by design. And it's a very common mistake developers make with regards to sockets.
To receive data correctly, you need to keep receiving data in a loop until you receive the number of bytes you need. Keep appending to your receive buffer until you get the number of bytes you need.
Some socket implementations have a the concept of a "wait for all" flag (e.g. MSG_WAITALL), but even that will return partial data if the remote closed the connection after sending.
Code defensively. Code as if the sender is only going to send 1 byte at a time. You'll be in good shape.
As you mentioned in your code, There might be more data, so you store the data received so far. But you don't have the code get the rest of the data.
MSDN has an example on how to do this correctly:
https://msdn.microsoft.com/en-us/library/bew39x2a.aspx?f=255&MSPPError=-2147217396
From winsock2.h:
#define MSG_WAITALL 0x8 /* do not complete until packet is completely filled */
You can add this option to your .net stream socket receive like this:
socket.Receive(buffer, (SocketFlags)0x8)
This should preserve message boundaries much like you're accustomed with dgram sockets.

Writing/reading string through NetworkStream (sockets) for a chat

Sorry if this is hard to understand, trying out C# for the first time.
I am trying to make a simple public 'chat' between clients that are connected to the server. I've tried passing integers to the server and printing them out and everything was fine, however,when I switched to strings, it seems that it can only pass 1 character (because of ns.Write(converted, 0, 1);). If I increase the ns.Write to ns.Write(converted,0,10) everything crashes (both the client and the server) when I enter a message that is less than 10 characters.
Server code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Net.Sockets;
namespace MultiServeris
{
class Multiserveris
{
static void Main(string[] args)
{
TcpListener ServerSocket = new TcpListener(1000);
ServerSocket.Start();
Console.WriteLine("Server started");
while (true)
{
TcpClient clientSocket = ServerSocket.AcceptTcpClient();
handleClient client = new handleClient();
client.startClient(clientSocket);
}
}
}
public class handleClient
{
TcpClient clientSocket;
public void startClient(TcpClient inClientSocket)
{
this.clientSocket = inClientSocket;
Thread ctThread = new Thread(Chat);
ctThread.Start();
}
private void Chat()
{
byte[] buffer = new byte[10];
while (true)
{
NetworkStream ns = clientSocket.GetStream();
ns.Read(buffer,0,1);
string line = Encoding.UTF8.GetString(buffer);
Console.WriteLine(line);
}
}
}
}
Client code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
namespace Klientas
{
class Klientas
{
static void Main(string[] args)
{
while (true)
{
TcpClient clientSocket = new TcpClient("localhost", 1000);
NetworkStream ns = clientSocket.GetStream();
byte[] buffer = new byte[10];
string str = Console.ReadLine();
byte[] converted = System.Text.Encoding.UTF8.GetBytes(str);
ns.Write(converted, 0, 1);
}
}
}
}
You're best using the BinaryReader/BinaryWriter classes to correctly format and read out data. This removes the need to process it yourself. For example in the client do:
BinaryWriter writer = new BinaryWriter(clientSocket.GetStream());
writer.Write(str);
And in the server:
BinaryReader reader = new BinaryReader(clientSocket.GetStream());
Console.WriteLine(reader.ReadString());
When using BinaryReader or BinaryWriter on the same stream, and you have .NET framework version 4.5 or above, be sure to leave the underlying stream open by using the overload:
using (var w = new BinaryWriter(stream, Encoding.UTF8, true)) {}

What's the recommended way for console applications to talk with each other?

I got a system of console applications written in C# running on different machines. I use MSMQ.
My questions is, how do I make my console applications communicate to each other?
I'm asking because I want to create a new console application that can be queried by other applications to know the number of messages in MSMQ.
Edit 1:
Thanks for the replies and comments!
About the requirements, I'm estimating maybe about 10-50/sec of queries
You need to use a pipe to achieve this: see Named pipe and anonymous pipe
A pipe works like this:
The host application (the one launching the console application) has to create a pipe to catch the concole application's std output and an other one to write to the console application's std input.
There is plenty of code example in the link I gave you
Also here is a code example (using existing pipes StandardInput and StandardOutput): it starts a cmd.exe console but it is a layer over: not the actual console...see for yourself:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.IO;
using System.Threading;
namespace ConsoleApplication1
{
class Program
{
private static StreamReader reader;
static void Main(string[] args)
{
Process cmd = new Process();
cmd.StartInfo.FileName = "cmd.exe";
cmd.StartInfo.RedirectStandardInput = true;
cmd.StartInfo.RedirectStandardOutput = true;
cmd.StartInfo.UseShellExecute = false;
cmd.Start();
reader = cmd.StandardOutput;
StreamWriter writer = cmd.StandardInput;
Thread t = new Thread(new ThreadStart(writingThread));
t.Start();
//Just write everything we type to the cmd.exe process
while (true) writer.Write((char)Console.Read());
}
public static void writingThread()
{
//Just write everything cmd.exe writes back to our console
while (true) Console.Write((char)reader.Read());
}
}
}
You can achieve the same result by replacing the StreamReader and the StreamWriter by a port connection (socket) buffer for remote communication between two process
http://msdn.microsoft.com/en-us/library/system.net.sockets.socket.aspx
It is recommended to secure the communication to minimize intrusion possibility
Here is an example of communication through a sockets...now this is running in one program but everything is on separate threads and it would work if the communication was to be on two separate machines: the server is the one controlling the process cmd.exe and the client is a viewer/writer
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.IO;
using System.Threading;
using System.Net.Sockets;
using System.Net;
namespace ConsoleApplication1
{
class Program
{
private static StreamReader reader;
private static StreamWriter writer;
static void Main(string[] args)
{
//Server initialisation
Process cmdServer = new Process();
cmdServer.StartInfo.FileName = "cmd.exe";
cmdServer.StartInfo.RedirectStandardInput = true;
cmdServer.StartInfo.RedirectStandardOutput = true;
cmdServer.StartInfo.UseShellExecute = false;
cmdServer.Start();
reader = cmdServer.StandardOutput;
writer = cmdServer.StandardInput;
Thread t1 = new Thread(new ThreadStart(clientListener));
t1.Start();
Thread t2 = new Thread(new ThreadStart(clientWriter));
t2.Start();
Thread t3 = new Thread(new ThreadStart(serverListener));
t3.Start();
Thread t4 = new Thread(new ThreadStart(serverWriter));
t4.Start();
}
public static void clientWriter()
{
Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
Int32 size = 0;
Byte[] buff = new Byte[1024];
sock.Connect(IPAddress.Parse("127.0.0.1"), 4357);
Console.WriteLine("clientWriter connected");
while (true)
{
String line = Console.ReadLine();
line += "\n";
Char[] chars = line.ToArray();
size = chars.Length;
if (size > 0)
{
buff = Encoding.Default.GetBytes(chars);
//Console.WriteLine("Sending \"" + new String(chars, 0, size) + "\"");
sock.Send(buff, size, 0);
}
}
}
/// <summary>
/// Local client that listens to what the server sends on port 4356
/// </summary>
public static void clientListener()
{
Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
sock.Bind(new IPEndPoint(IPAddress.Any, 4356));
sock.Listen(0);
Int32 size = 0;
Byte[] buff = new Byte[1024];
Char[] cbuff = new Char[1024];
while (true)
{
Console.WriteLine("clientListener Waiting for connection");
sock = sock.Accept();
Console.WriteLine("clientListener Connection accepted " + ((sock.Connected)?"Connected" : "Not Connected"));
while ((size = sock.Receive(buff)) > 0)
{
for (int i = 0; i < size; i++) cbuff[i] = (Char)buff[i];
Console.Write(cbuff, 0, size);
}
sock.Close();
}
}
/// <summary>
/// Remote server that listens to what the client sends on port 4357
/// </summary>
public static void serverListener()
{
Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
sock.Bind(new IPEndPoint(IPAddress.Any, 4357));
sock.Listen(0);
Int32 size = 0;
Byte[] buff = new Byte[1024];
Char[] cbuff = new Char[1024];
while (true)
{
Console.WriteLine("serverListener Waiting for connection");
sock = sock.Accept();
Console.WriteLine("serverListener Connection accepted " + ((sock.Connected) ? "Connected" : "Not Connected"));
while ((size = sock.Receive(buff)) > 0)
{
for (int i = 0; i < size; i++) cbuff[i] = (Char)buff[i];
//Console.WriteLine("Received \"" + new String(cbuff,0,size) + "\"");
writer.Write(cbuff, 0, size);
}
}
}
/// <summary>
/// Remote server that writes the output of the colsole application through the socket
/// </summary>
public static void serverWriter()
{
Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
Int32 size = 0;
Byte[] buff = new Byte[1024];
Char[] cbuff = new Char[1024];
sock.Connect(IPAddress.Parse("127.0.0.1"), 4356);
Console.WriteLine("serverWriter connected");
while (true)
{
size = reader.Read(cbuff, 0, 1024);
if (size > 0)
{
for (int i = 0; i < size; i++) buff[i] = (Byte)cbuff[i];
sock.Send(buff, 0, size, 0);
}
}
}
}
}
testable and extendable - can be easily changed to work between computers.
you have a few methods. "named pipes" can be achieved easily using WCF. its nice because its very testable.
best performance you can use memory mapped files http://weblogs.asp.net/gunnarpeipman/archive/2009/06/21/net-framework-4-0-using-memory-mapped-files.aspx
they have AMAZING performance. BUT less harder to test.
easiest - if you have very low traffic you can use the registry. theres a Regisrty class in C# its threadsafe and fast.
WCF. WCF, WCF, WCF, WCF.
Don't bother reinventing the wheel, just use WCF for communications, and let it worry about the details (whether using a pipe or some other mechanism).

Unable to view any received data

I'm implementing really simple UDP server in C# language.
When I implemented the server on Console based application, it worked well.
But when I implemented it by using the same code on Windows based application,
it doesn't works as before.
I guessed that it is the problem of thread thing.
So I putted thread on the code, but still doesn't works.
The function of "ReceiveFrom()" doesn't works as before.
numReceived = udpSocket.ReceiveFrom(buffer, ref remoteEP);
what is a problem that I'm missing?
Thank you in advance.
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.Runtime.InteropServices;
using System.Net;
using System.Net.Sockets;
using System.Threading;
namespace UDP_Server
{
public partial class Form1 : Form
{
private const int portNum = 5432;
Socket udpSocket;
byte[] buffer = new Byte[100];
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
ThreadStart threadStart = new ThreadStart(onServer);
Thread thread = new Thread(threadStart);
thread.Start();
}
private void onServer()
{
EndPoint localEP = new IPEndPoint(IPAddress.Parse("xxx.xxx.xxx.xxx"), portNum);
//EndPoint remoteEP = new IPEndPoint(IPAddress.Any, 0);
udpSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
udpSocket.Bind(localEP);
ThreadStart threadStart1 = new ThreadStart(OnReceive);
Thread thread1 = new Thread(threadStart1);
thread1.Start();
//udpSocket.BeginReceiveFrom(buffer, 0, buffer.Length,
//SocketFlags.None, ref remoteEP, new AsyncCallback(OnReceive), (object)this);
}
private void OnReceive()//IAsyncResult ar)
{
int numReceived = 0;
EndPoint remoteEP = new IPEndPoint(IPAddress.Any, 0);
Console.WriteLine("UDP Starting Server");
Console.WriteLine("-----------------------------");
while (true)
{
numReceived = udpSocket.ReceiveFrom(buffer, ref remoteEP);
string s = Encoding.UTF8.GetString(buffer, 0, numReceived);
Console.WriteLine("Echo : {0}", s);
}
}
}
}
Looks as if your expecting it to print some output (which it is via the console window).You need to add all of the output you want to display in a windows forms control such as a rich text box and do:
RichTextbox1.Text += yourInput;

Categories