Matlab can not read the socket for the second time - matlab

I want to communicate between two programs. MATLAB is able to read the socket once but when it tries to read it again, I get the following warning
Warning: Unsuccessful read: A timeout occurred before the Terminator was reached.
Matlab code:
clc
clear all
while(1)
clear tcpipServer
tcpipServer = tcpip('127.0.0.1', 55000, 'NetworkRole', 'Server');
set(tcpipServer, 'Timeout', 30);
fopen(tcpipServer);
rawData = fgetl(tcpipServer);
fclose(tcpipServer);
end
The data which is sent to Matlab is defined as string and the value is "y\n".
The problem is that I only receive "y\n" once.
The other side connected to the socket is the Unity game engine. I think the code in the unity is correct because I tested that by c# windows app and I can get the value as long as program is running.
Does anyone know why this is happening?

This is the solution i found.
Matlab code:
clc
clear all
%% server initialization
tcpipServer = tcpip('127.0.0.1',55000,'NetworkRole','Server');
set(tcpipServer,'Timeout',30);
while(1)
%% server code: listening for incoming requests
fopen(tcpipServer);
%rawData = fread(tcpipServer,1,'char');
rawData = fgetl(tcpipServer)
extractedData=str2double(strsplit(rawData,'-'))
fclose(tcpipServer);
Unity C# code:
using UnityEngine;
using System.Collections;
using System.Net;
using System.Net.Sockets;
using System.Linq;
using System;
using System.IO;
using System.Text;
public class server : MonoBehaviour {
// Use this for initialization
TcpListener listener;
String msg;
StreamWriter theWriter1;
internal Boolean socketReady = false;
TcpClient mySocket;
NetworkStream theStream;
StreamWriter theWriter;
StreamReader theReader;
String Host = "localhost";
Int32 Port = 55000;
bool firstTimeRun=true;
void Start () {
}
// Update is called once per frame
void Update () {
setupSocket ();
if (Input.GetMouseButtonDown (0))
{
setupSocket ();
}
}
public void setupSocket() {
try {
TcpClient mySocket1;
NetworkStream theStream1;
//StreamWriter theWriter1;
mySocket1 = new TcpClient(Host, Port);
theStream1 = mySocket1.GetStream();
theWriter1 = new StreamWriter(theStream1);
Invoke("write", 0.2f);
}
catch (Exception e) {
Debug.Log("Socket error: " + e);
}
}
void write()
{
float x;float y;
x = GameObject.FindGameObjectWithTag ("Player").transform.position.x;
y=GameObject.FindGameObjectWithTag ("Player").transform.position.y;
theWriter1.Write(x+"-"+y+"\n");
theWriter1.Flush();
}
The reason I used "\n" is using fgetl function in Matlab code. if you want to make the code more functional use delay along with Asynchronous tasks in Unity. for those wandering why using delay is required, see the comments under question.

Related

Connecting Unity client to XMPP server

I'm trying to make a client for chat using unity.
I have found this library https://github.com/bilelmnasser/Unity-3D-Xmpp-Protocol-
so I've imported to my project and being testing the code but I can't seem to get it to work.
using UnityEngine;
using Xmpp;
using Xmpp.protocol.client;
public class NewBehaviourScript : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
var xmppClient = new XmppClientConnection("localhost");
//xmppClient.ConnectServer = "ipServer";
xmppClient.Server = "localhost";
xmppClient.Port = 5222;
xmppClient.Username = "admin#localhost";
xmppClient.Password = "password";
xmppClient.Open();
xmppClient.OnLogin += delegate(object o) { xmppClient.Send(new Message("user#localhost", MessageType.chat, "Hello, how are you?")); };
}
Here is my code. I have a ejabberd server running using docker.
I've created two users and tested on node server as client and it worked fine, but can't get to work on unity...
any help would be great!

How to make sockets work in xamarin?

In the Answer to this question Here:Server Client Application with .NET and Xamarin
the person who answered said: "On Xamarin.Android you can use all of the regular .Net socket classes"
I tried using the code in example of the Microsoft documentation and i had no errors but application just is just displaying like that on the phone:
If I delete the socket code it would display the page normally.My code behind:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
using System.Net;
using System.Net.Sockets;
namespace App14
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class Page2 : ContentPage
{
public static string data = null;
public static void StartListening()
{
// Data buffer for incoming data.
byte[] bytes = new Byte[1024];
// Establish the local endpoint for the socket.
// Dns.GetHostName returns the name of the
// host running the application.
IPHostEntry ipHostInfo = Dns.GetHostEntry(Dns.GetHostName());
IPAddress ipAddress = ipHostInfo.AddressList[0];
IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 11000);
// Create a TCP/IP socket.
Socket listener = new Socket(ipAddress.AddressFamily,
SocketType.Stream, ProtocolType.Tcp);
try
{
listener.Bind(localEndPoint);
listener.Listen(10);
// Start listening for connections.
while (true)
{
var label = new Label() { Text = "searching for a connection" };
// Program is suspended while waiting for an incoming connection.
Socket handler = listener.Accept();
label.Text = "Found a Connection";
data = null;
// An incoming connection needs to be processed.
while (true)
{
int bytesRec = handler.Receive(bytes);
data += Encoding.ASCII.GetString(bytes, 0, bytesRec);
if (data.IndexOf("<EOF>") > -1)
{
break;
}
}
// Show the data on the console.
label.Text = "Text received" + data;
// Echo the data back to the client.
byte[] msg = Encoding.ASCII.GetBytes(data);
handler.Send(msg);
handler.Shutdown(SocketShutdown.Both);
handler.Close();
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
public Page2 ()
{
StartListening();
Title = "Sign in page";
InitializeComponent();
}
private void page2_click(object sender,EventArgs e)
{
Navigation.PushAsync(new Page1(), true);
}
}
}
Xaml File code:
Why is this?.and can you please provide an example of client mobile or server mobile socket
You are blocking the UI Thread with your StartListening call, since it has a infinite while loop.
The label you create in the while loop is never added as content on the page. Hence the text you add to it will never be shown. You already have a label defined with the name l on the page. In this case you could just use that to add text:
l.Text = "hello";
As commented, you should start your socket listening code on another thread to not block you UI. This could be as simple as writing Task.Run(() => StartListening());. Make sure you understand what this does and possibly how you cancel this Task again when navigating away from the page or during App lifecycle.
If you try to Connect from your mobile with the correct ip address and port number of the Listener when both devices are in the same LAN it should work. If one of the devices is behind a different LAN router/modem you won't be able to connect because the router will block all incoming connections unless you use a port routing mechanism like UPnP.

TCPClient will only ever connect once

I am building an app that communicates to a machine via TCP. The issue I have is that I can connect and all is well but once I disconnect and then try and reconnect all I get is error
The code I have in the form is
private void btn_connect_Click(object sender, EventArgs e)
{
try
{
Log(LogMsgType.Normal, String.Format("Connected on {0}\n", DateTime.Now));
string ip = (txt_ipadd_1.Text + "." + txt_ipadd_2.Text + "." + txt_ipadd_3.Text + "." + txt_ipadd_4.Text);
Log(LogMsgType.Normal, String.Format("Connecting to IP address " + ip + " Port # " + txt_port.Text +"\n"));
string con = Codenet.Connect_TCP(ip, Convert.ToInt32(txt_port.Text)); //connect to this one
Log(LogMsgType.Normal, String.Format(con + "\n"));
toolStripStatusLabel1.Text = "Connected";
btn_connect.Visible = false;
btn_disconnect.Visible = true;
ip = "";
}
catch (Exception d)
{
Log(LogMsgType.Error, String.Format("Error..... " + d.StackTrace +"\n"));
}
}
Which goes over to code from the Codenet dll which does the connection and disconnection
public static string Connect_TCP(string ip, int Port)
{
tcpclnt.Connect(ip, Port);
connection_type = "TCP";
return "Connected OK ";
}
public static void DisConnect_TCP()
{
tcpclnt.GetStream().Close();
tcpclnt.Close();
}
The error I get is:
Error..... at System.Net.Sockets.TcpClient.Connect(String hostname, Int32 port) at
comms_engine.Codenet.Connect_TCP(String ip, Int32 Port) in C:\a\code\g_com_test_1\comms_engine\Codenet.cs:line 37 at
comms_test.CommTester.btn_connect_Click(Object sender, EventArgs e) in C:\a\code\g_com_test_1\dll_test\ethernet.cs:line 98
It will not perform the tcpclnt.Connect(ip, Port) even if the ip is different.
It seems that something is still open but what I do not know as the machine has disconnected. I know that as I have UDP in it sending out how many connections it has and I can see then increase and decrease OK.
I tried "public string Connect_TCP(string ip, int Port)" and making a NEW instance of the dll befor calling the connect from the form but that did not work either.
Any ideas what I am doing wrong.
Thanks for answers so far but still I have an issue. I read the MSDN and made a test app and I can now see what is wrong but am clueless on how to fix it at the moment. I am declaring the Client as Static global so I can get it from the connect and disconnect button. I think thta this always creates new instances and I never close them. First time round the machine tells me it has diconnected bu t the app never reconnects In debug mode it falls over at client.Connect(ipEndPoint); with "InvalidOperationException was unhandled" followed by "Once the socket has been disconnected, you can only reconnect again asynchronously, and only to a different EndPoint. BeginConnect must be called on a thread that won't exit until the operation has been completed."
I guess I need to put this Client inside the btn_connect_click and get a pointer to it from inside the disconnect but how?
The full code is
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.Net;
using System.IO;
using System.IO.Ports;
using System.Diagnostics;
using System.Threading;
namespace TCP_Test
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
static Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
private void btn_connect_Click(object sender, EventArgs e)
{
string ip = (txt_ipadd_1.Text + "." + txt_ipadd_2.Text + "." + txt_ipadd_3.Text + "." + txt_ipadd_4.Text);
IPHostEntry ipHost = Dns.GetHostEntry(Dns.GetHostName());
IPAddress ipAddr = IPAddress.Parse(ip);
IPEndPoint ipEndPoint = new IPEndPoint(ipAddr, Convert.ToInt32(txt_port.Text));
// Connect the socket to the remote end point.
client.Connect(ipEndPoint);
rchTxtBx_output.AppendText("connected to " + ipEndPoint + "\n\r");
}
private void btn_disconnect_Click(object sender, EventArgs e)
{
client.Shutdown(SocketShutdown.Both);
client.Disconnect(true);
if (client.Connected)
rchTxtBx_output.AppendText("We're still connnected \n\r");
else
rchTxtBx_output.AppendText("We're disconnected \n\r");
}
}
}
Once you disconnect a TCP socket, it cannot be reconnected. You have to release the socket and create a new one. This is not just limited to the .NET TCPClient class, this is how all socket APIs work in general (WinSock, BSD, etc).
The exception to this rule is the WinSock2-specific DisconnectEx() function, which has a TF_REUSE_SOCKET flag that allows ConnectEx() (and AcceptEx()) to re-use an existing SOCKET instead of requiring a new socket to be created. But that does not apply in your situation.
In the majority of cases, once you disconnect a socket, you have to create a new socket from scratch.
Thanks for the help I have now solved it. See above for full code but below is teh snippet that makes it work. Just add client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); inside the connect button. My testing now shows it connects and disconnects and allows reconnect or connect to anothe machine. Only took me two man days to work that out with your help.
static Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
private void btn_connect_Click(object sender, EventArgs e)
{
if (client.Connected)
{
client.Shutdown(SocketShutdown.Both);
client.Disconnect(true);
client.Close();
}
else
{
client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
try
{
string ip = (txt_ipadd_1.Text + "." + txt_ipadd_2.Text + "." + txt_ipadd_3.Text + "." + txt_ipadd_4.Text);
IPHostEntry ipHost = Dns.GetHostEntry(Dns.GetHostName());
When the connection is closed, underlying socket(TCPClient.Client returns socket) needs to be set for reuse . Use the Socket.Disconnect(true) instead of close to reconnect on the socket. Check the link:
http://msdn.microsoft.com/en-us/library/system.net.sockets.socket.disconnect(v=vs.90).aspx

Is it possible to get audio data from the users audio device using NAudio to pass to Unity3D for visualization

What I am trying to do is grab the raw audio from the users audio output take that data and get an audio spectrum and output array similar to unity3d and pass that data to my visualizer.
So a couple things I need to know:
Can I grab the raw audio from the users device? What I have found so far is yes using waveinstream which by default gets audio data from all devices.
Can I grab the audio spectrum and output from that data similarly to Unity3D GetOutputData() and GetSpectrumData()? the NAudio demo provides similar functionality but not exactly what I want.
I am a newbie with coding naudio, whereas unity's API and extremely thorough documentation make it easier, naudio seems to have a couple tutorials and examples, nothing of what I need, and no API definitions. I will eventually figure it out but what I need to know is if what I'm attempting is possible, other than that any help is appreciated.
I provided my attempt at problem 1 which provides seemingly random data which I am trying to make sense of using a WaveFileReader but that crashes
using UnityEngine;
using System.Collections;
using System;
using NAudio.Wave;
using NAudio.CoreAudioApi;
using NAudio.Utils;
public class myNAudio : MonoBehaviour {
private WaveIn waveInStream;
private WaveFileReader reader;
private WaveStream readerStream;
void waveInStream_DataAvailable(object sender, WaveInEventArgs e){
//reader.Read(e.Buffer,0,e.BytesRecorded);
//Debug.Log(e.Buffer);
float tempDB = 0;
for(int i = 0; i < e.Buffer.Length; i++){
//Debug.Log(i + " = " +e.Buffer[i]);
tempDB += (float)e.Buffer[i]/255;
}
Debug.Log(e.Buffer.Length + ", " +tempDB);
}
void OnApplicationQuit(){
waveInStream.StopRecording();
waveInStream.Dispose();
waveInStream = null;
}
void OnDisable(){
waveInStream.StopRecording();
waveInStream.Dispose();
waveInStream = null;
}
// Use this for initialization
void Start () {
waveInStream = new WaveIn();
waveInStream.DeviceNumber = 0;
waveInStream.DataAvailable += new EventHandler<WaveInEventArgs>(waveInStream_DataAvailable);
waveInStream.StartRecording();
}
// Update is called once per frame
void Update () {
}
}

Reset performance counter from command line

I want to execute a command from command line to reset given performance counter to 0.
I could write a simple "3" lines console app to do that, but wondering if VS or Windows or Windows SDK already comes with such utility. I did not find such option in either typeperf or logman.
Context:
Windows 7 x64 (with Admin access)
Background:
I use a performance counter to debug/develop/stress-test a web service. Web service increments a performance counter every time it is hit.
So the scenario is to hit web service 10000 times and verify no messages have been lost (I test MSMQ + out-of-order processing + persistence + Windows Workflow Service)
While I'm waiting for a better answer, here is a complete "rstpc.exe" utility to reset performance counter (of NumberOfItems32 type):
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
namespace ResetPerformanceCounter
{
internal class Program
{
private static int Main(string[] args)
{
if (args.Length != 2)
{
string fileName = Path.GetFileName(Assembly.GetExecutingAssembly().Location);
Console.WriteLine("Usage: {0} <PC Category> <PC Name>", fileName);
Console.WriteLine("Examlpe: {0} {1} {2}", fileName, "GEF", "CommandCount");
return -1;
}
string cat = args[0];
string name = args[1];
if (!PerformanceCounterCategory.CounterExists(name, cat))
{
Console.WriteLine("Performance Counter {0}\\{1} not found.", cat, name);
return - 2;
}
var pc = new System.Diagnostics.PerformanceCounter(cat, name, false);
if (pc.CounterType != PerformanceCounterType.NumberOfItems32)
{
Console.WriteLine("Performance counter is of type {0}. Only '{1}' countres are supported.", pc.CounterType.ToString(), PerformanceCounterType.NumberOfItems32);
return -3;
}
Console.WriteLine("Old value: {0}", pc.RawValue);
pc.RawValue = 0;
Console.WriteLine("New value: {0}", pc.RawValue);
Console.WriteLine("Done.");
return 0;
}
}
}