The NetworkCursor you linked to does not use c-plugins, just C-Sharp and JavaScript all perfectly available from Indie. What’s probably confusing is that some of the code goes into the Plugins folder. This is just a weird quirk of Unity that is explained here:
I’ve also added a few network scripts to the Wiki (I just forgot to put them under the Networking scripts section). I put them there now. One is a Server which is an extension of NetworkCursor, the other is Sender which sends along the name of the root, parent, and a string. I’ve been using this to do some robot simulation communicating with a Java based robot controller. Works quite well.
I’ve had no luck so far. No happy bleeps going between my applications.
I am trying to setup a ftp client in Unity that can send data to the flashserver object in Max/MSP. I have reused the code from the NetworkCursor example.
In my Plugins folder I have two pieces of code; Client.cs and MessageData.cs. These look like this:
// Client //
using UnityEngine;
using System.Collections;
using System.Net.Sockets;
using System.Net;
public class Client : MonoBehaviour {
public string m_IPAdress = "192.168.0.100";
public const int kPort = 7777;
private static Client singleton;
private Socket m_Socket;
void Awake ()
{
m_Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
System.Net.IPAddress remoteIPAddress = System.Net.IPAddress.Parse(m_IPAdress);
System.Net.IPEndPoint remoteEndPoint = new System.Net.IPEndPoint(remoteIPAddress, kPort);
singleton = this;
m_Socket.Connect(remoteEndPoint);
}
void OnApplicationQuit ()
{
m_Socket.Close();
m_Socket = null;
}
static public void Send(MessageData msgData)
{
if (singleton.m_Socket == null)
return;
byte[] sendData = MessageData.ToByteArray(msgData);
byte[] prefix = new byte[1];
prefix[0] = (byte)sendData.Length;
singleton.m_Socket.Send(prefix);
singleton.m_Socket.Send(sendData);
}
}
// MessageData //
using UnityEngine;
using System.Collections;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
[System.Serializable]
public class MessageData {
public float currentTime = 0;
public static byte[] ToByteArray (MessageData msg)
{
// Create a memory stream, and serialize.
MemoryStream stream = new MemoryStream();
// Create a binary formatter.
BinaryFormatter formatter = new BinaryFormatter();
// Serialize.
formatter.Serialize(stream, msg.currentTime);
// Now return the array.
return stream.ToArray();
}
}
In my scripts folder I have ClientSend.js whice looks like this:
// ClientSend //
function Update ()
{
// Create the message it and send it off!
var msgData = new MessageData();
msgData.currentTime = Time.time;
Client.Send(msgData);
}
Client.cs and ClientSend.js is attached as components to a empty object in the scene.
Since I’m running both server (Max/MSP) and client (Unity) on the same computer, I insert that computers IP address in Client.cs. This confused me though, there is a IP for ethernet and IP for airport. I tried both without luck. The port is also set to 7777 in the flashserver object (Max/MSP).
I start the flashserver patch
I start the Unity application
Unity hangs for about a minute.
Unity returns this error message:
SocketException: The socket has been shut down
System.Net.Sockets.Socket.Send (System.Byte[] buf) [0x00000]
Client.Send (.MessageData msgData) (at Assets/Plugins/Client.cs:40)
My knowledge about networking and sockets is very limited, so I might be making a very simple mistake.
First make sure you can connect to the FTP server. Use the termianl to telnet to the server “telnet ” if you are running on the same machine “telnet localhost 7777” if you are using port 7777.
Second make sure the socket is connecting correctly from Unity. Remove the Client.Send from Update, that’s sending a lot for debugging. Just try and print out some messages using Debug.Log after the connection is accepted.
Third, it is possible that the FTP server doesn’t understand what you’re sending (message format is bad) it and since you are sending every frame kills the connection after a while. This would give the “socket has been shut down” error.
Fourth, the socket is set to block by default so if it can’t send it just sits there and keeps on trying, meanwhile everything else is held up. This is probably why Unity hangs. You can set the socket to be non-blocking using the following code.
m_Socket.Blocking=false;
This will simply throw a SocketException (instead of blocking) which you can handle however you choose.
Try these things and see how it goes. I’ll post a new version of my server code on the wiki that handles the blocking stuff.
FIRST: telnet via Terminal.
Aha! The ‘flashserver’ object makes Max/MSP crash when you send to it from Terminal, but the ‘mxj net.tcp.recv’ object recieves fluently.
SECOND: check if socket is connected
How can I check this using Debug.Log()?
THIRD: the FTP server doesn’t understand the input.
That might be. Messaging works through Terminal How can I mimic the messages Terminal sends?
FOURTH: m_Socket.Blocking=false
Unity still hangs, but it throws a new error here:
First, to connect to local host use 127.0.0.1 as the IP.
Second, to use Debug.Log, use something like Debug.Log("Socket is Connected? " + m_socket.Connected); which should print true or false along w/ that statement. Do that after the m_socket.Connect();
Third, The terminal just sends text strings, so take a look at my Server/Sender code on the wiki, this is exactly what that does.
Fourth, just put some Debug.Log(“Mooo1”); Debug.Log(“Mooo2”); type messages around your code so you can find out where the error is coming from if Unity doesn’t tell you. What is the rest of that error message? Or is that it?
OK Unity won’t reply unless you tell it to… My code doesn’t reply when it receives a message and the code you have should appear in the Unity console. Also if you are running Unity on 7777 then whatever is on 8888 is not Unity (unless I misunderstood and you did 2 builds). The closed by foreign host message is Telnet saying the connection was closed properly from the other side. You can add Debug.Log code in the section of the server code that reads from the socket to make sure it is receiving characters. Really the Server code as is should work (I’m using it now), but it doesn’t reply. To send a reply use Server.PutMessage(“some string”);
Haven’t read the thread thoroughly enough, but when I ran Unity in a client/server architecture (different code though), I had problems due to the fact that Unity is not running in the background. This might help:
Application.runInBackground = true;
On my computer the flashserver object makes Max/MSP 1.6.2 crash, just by opening it, so I use mxj net.tcp.recv and mxj net.tcp.send instead. They work fine when I test with telnet in Terminal.
Jeff:
I should have been more precise here, by ‘not replying’ I meant that nothing pops up in the Unity console.
The Connected function never returns true, so there is no input to check so far.
I must be doing something wrong then.
This ‘should’ pop up text in the Unity console, right?
Put Server.cs as it is in the Plugins folder and attach it to a GameObject in the scene.
I manged to post around 8 replies because I kept getting an error message when I posted. I hope you didn’t recieve around 8 email notifications as well. Sorry about that.
OK just to be clear, you are trying to connect to the Unity server from telnet right? Not the Max/MSP? And are only running Unity at the moment, correct? The existing code should put “Did connect” in the Unity console if you connect to it successfully. Line 181 of Server.cs does that. Also I’ve got mine in Standard Assets/Scripts so it compiles before any other stuff in the Assets folder.
Now it works with Terminal and Unity only. I have no clue why it didn’t work before, so the happy news comes with a grain of bitterness. Frustrating actually. It’s doesn’t matter if I put Server.cs in Scripts, Plugins or Standart Assets/Scripts ? it all works.
I also managed to send messages from Max via the net.tcp.send object!
Now my next task is to get messages flowing from Unity to Max. I can’t simply use Server.cs for that, because the net.tcp.send object disconnects automatically just after it sends the message, so Server.cs has no registred client to send back to. http://www.cycling74.com/story/2005/5/2/134847/8926
I’ll look into this and probably return with more specified questions.
OK the socket used for the incoming connection should have all the info you need to create a new outgoing connection (with maybe the exception of the port #). So if you know what port the Max code listens on, you can get the IP from the socket and then make a new socket connection with that info, send your data and close the socket. This creation of a new socket connection would happen every time a message from the queue is sent.