I'm working on a project for my friend and I need to implement communication between windows forms app and unity android app but I don't know how. Example of my code:
Unity:
Class program
{
Public InputField password;
Public static void Loggin ()
{
String localpass = password.text;
String winpass = //passS from WinForm code
If (localpass == winpass)
Mytextbox.text = "success";
Else
Mytextbox.text = "wrong password";
}
}
WinForm:
Public static void myVoid ()
{
String passS = File.ReadLines(App domain.CurrentDomain.BaseDirectory + #"\\mytextfile.txt").ElementAtOrDefault(3);
}
Direct communication
Socket programming is your friend. This means that the two applications are aware of each other, or at least one of them (the client) is aware of the other (the server)
C# example of a tcp/ip listener
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net; //required
using System.Net.Sockets; //required
namespace ServerTest
{
class Program
{
static void Main(string[] args)
{
TcpListener server = new TcpListener(IPAddress.Any, 9999);
// we set our IP address as server's address, and we also set the port: 9999
server.Start(); // this will start the server
while (true) //we wait for a connection
{
TcpClient client = server.AcceptTcpClient(); //if a connection exists, the server will accept it
NetworkStream ns = client.GetStream(); //networkstream is used to send/receive messages
byte[] hello = new byte[100]; //any message must be serialized (converted to byte array)
hello = Encoding.Default.GetBytes("hello world"); //conversion string => byte array
ns.Write(hello, 0, hello.Length); //sending the message
while (client.Connected) //while the client is connected, we look for incoming messages
{
byte[] msg = new byte[1024]; //the messages arrive as byte array
ns.Read(msg, 0, msg.Length); //the same networkstream reads the message sent by the client
Console.WriteLine(encoder.GetString(msg).Trim('')); //now , we write the message as string
}
}
Create an api to communicate
The options are unlimited. Create a rest api using WebApi 2 or any other technology to periodically hit and check for data updates.
This communication is asynchronous and not direct, so you should account for that in some way.
Use push notifications
Mobile applications can get push notifications. If the communication is not bidirectional, this on its own could be a solution.
If it is, then the mobile application could communicate via an api and the forms application via push notifications
Check https://gamedev.stackexchange.com/questions/157009/how-can-i-send-android-notifications-from-my-unity-game#
There are many ways to do this. If you are only communicating locally. Try socket programming, Use TCP/IP for communication between the two programs.
Try this link for a start
Or if you want to connect over a network try WCF can also work out
Try this link for a WCF fresh start (this is Slower)
or you can use SignalR web sockets
Try this link for ASP NET CORE SignalR
Another way is to use RabbitMQ
Try this link for RabbitMQ documentation
And there many more ways.
Related
Hello,
I am trying to set up a UDP connection in Unity3d and it has been giving me some headace the past days:
The Unity script I am running is supposed to receive and maybe in the future send UDP messages.
Next to Unity I am using Wireshark to track the packets and PacketSender to generate and receive UDP messages.
The source of the messages is a PLC which sends a package every second, containing two floats (8 bytes) for testing.
The PLC IP is 192.168.0.1 and it is connected directly via Ethernet to the Laptop running Unity. (no switch, no router)
My Ethernet Port has the IP 192.168.0.41, and the messages are coming in via Port 8052.
What I can see in Wireshark via :
Packages arriving from the PLC to Unity
Packages leaving from Unity to the PLC
The packages have the expected structure
What I can see / do in PacketSender:
packages arriving from the PLC (via Port 8052)
send messages to the PLC that are visible in Wireshark
by receiving the packages here it should also be safe to say that the firewall port window works.
I can NOT receive packages with PacketSender if I already started my Unity-receive script...
... which should be an indicator, that the Unity UDP socket is up and running, hopefully swallowing messages.
If I call netstat -aon I can see the Unity UPD Process at the expected Port & IP;
0.0.0.0:8052 or 192.168.0.41:8052, depending on how it is created. Also I can see that no other process is using the same port.
But what does not work is to actually receive and use the data in my Unity script.
What works is to receive data send via the local IP 127.0.0.1 from another Unity script.
By now I have tried several ways to create a socket:
var udpClient = new UdpClient(8052,AddressFamily.InterNetwork)
var udpClient = new UdpClient(8052)
UdpClient udpClient = new UdpClient(8052,AddressFamily.InterNetwork)
var udpClient = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
I have tried...
...to receive the messages sychronous or asychronous
...to run the receive-loop in the Main thread or in a background thread
...to en-/disable blocking of the client
...to bind the client to an IP or leave it on IPAddress.Any
...to shut down the HyperV switch I had on the Ethernet Port (still shut down)
...to open the relevant ports in the firewall
...to restart the laptop
...about every solution I could find in any forum.
It feels like either the C# socket and the Step7 socket speak a different UDP or the C# socket is not functioning on the receiving side as expected.
The package is really at the doorstep of the socket and it ignores it.
Setup specs:
PLC: CPU315-2 PN/DP
Laptop: Dell Latitude, i5, 8GB RAM, Win10 Enterprise, 64-bit
Unity: Unity 2017.3.1f1, Only asset is PlayMaker
Current test code:
using System;
using System.Net;
using System.Net.Sockets;
using UnityEngine;
using System.Threading;
public class UDPReceive03 : MonoBehaviour
{
Thread receiveThread;
public UdpClient socket;
private bool canReceive;
public static bool messageReceived;
public String statusThread;
public int UDP_LISTEN_PORT;
private int alive;
// Use this for initialization
void Start()
{
UDP_LISTEN_PORT = 8052;
print("started");
canReceive = true;
messageReceived = false;
alive = 0;
receiveThread = new Thread(new ThreadStart(ReceiveData));
receiveThread.IsBackground = true;
receiveThread.Start();
}
// Update is called once per frame
void Update()
{
// I know the code below is ugly, but that was my rebellion agains the situation
statusThread = (canReceive) ? "Waiting" : "Busy";
if (alive % 180 == 0)
sendResponse(1);
alive = (alive<180) ? alive + 1 : 1;
}
private void ReceiveData()
{
using (var udpClient = new UdpClient(8052,AddressFamily.InterNetwork))
{
int loggingEvent = 0;
while (true)
{
print("started to receive");
IPEndPoint remoteEndPoint = new IPEndPoint(IPAddress.Any, 0);
var receivedResults = udpClient.Receive(ref remoteEndPoint);
loggingEvent += receivedResults.Length;
print("Success, received " + loggingEvent.ToString() + " bytes.");
sendResponse(loggingEvent);
}
}
}
private void sendResponse(int count)
{
socket = new UdpClient(8051);
// sending data
IPEndPoint target = new IPEndPoint(IPAddress.Parse("192.168.0.1"), 2000);
// send a couple of sample messages:
for (int num = 1; num <= count; num++)
{
byte[] message = new byte[num];
socket.Send(message, message.Length, target);
}
socket.Close();
}
}
I am aware of the lack of comments in the code, but as you might have guessed, the code changed a lot lately.
Thank you for the help.
If you want to receive from external source you need to allow Unity on firewall or disable firewall. Firewall blocks unity editor connection with external source, that is why you can send data but can not receive. If you build your project, your code will work, because it will ask you on first running
So after a very frustrating journey I found a work-around that is not nice but does the job:
I wrote a python script that opens a socket, receives the external data and forwards it via the local IP to Unity. And that works.
Here is the code:
# Import libraies
import socket
import time
# Set send IP adress and port
UDP_IP = "127.0.0.1"
UDP_PORT_Rec = 8052
UDP_PORT_Unity = 8055
print("Receiving on Port:" + str(UDP_PORT_Rec))
print("Sending to IP:" + UDP_IP + ":" + str(UDP_PORT_Unity))
# Set socket to send udp messages and bind port
sock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
sock.bind(('',UDP_PORT_Rec));
## Keep sending message from file location
while True:
data, addr = sock.recvfrom(1024) #buffer size, hopefully no problem if too big
print("Received")
sock.sendto(data, (UDP_IP, UDP_PORT_Unity))
print("Send")
Tools that are useful for your trouble shooting:
Install Wireshark! It is probably the best tool out there to track Internet traffic. Packages that are visible in Wireshark might not be visible for a normal application!
Use Packet Sender to generate and receive traffic. The application uses a basic approach to receive packages - If it can then your programm should be able to as well.
Check with netstat -aon if your socket is running.
For completion: Check your firewall settings.
I'm trying to read incoming messages using a TcpListener. I set up a listener and I get a message. But the message is very strange. I'm getting this:
▬♥♥¡☺?♥♥YÄÂb #ù÷"MDòs←ç→.ge ûjò8┼#i(♥→å:À#À'<À%À)g#À À‼/À♦À♫32À+À/oÀ-À1z¢À↕▬‼ÿ☺:▬¶↨↑↓▬¶♠♥♠☺♣♥♣☺♦♥♦☺♦☻☻♥☻☺☻☻
The message is sent from another application (I don't have the source code of this application) over https (is it possible that the https is the problem?). Anyway, the listener I set up looks like this:
static void Main(string[] args)
{
TcpListener listener = new TcpListener(IPAddress.Parse("127.0.0.1"), 11000);
Console.WriteLine("Listening...");
listener.Start();
TcpClient client = listener.AcceptTcpClient();
Console.WriteLine("Connection accepted.");
Thread t = CreateThread(client, false);
t.Start();
}
private static Thread CreateThread(TcpClient client)
{
Thread t = new Thread(delegate ()
{
byte[] data = new byte[300];
client.Client.Receive(data);
Console.WriteLine("Received data: ");
string value = Encoding.Default.GetString(data);
Console.WriteLine(value);
});
return t;
}
The message should be a valid xml tree. I'm using C# and .NET framework 4.5.2. What exactly am I doing wrong?
As the comments have said, it would appear that you're trying to get the data at a low level on the OSI model. Instead of using a TcpClient you can use a HttpClient to get the data from the application you're listening to.
Although it does depend on what your server is and how requests are handled.
var httpClient = new HttpClient();
var response = await httpClient.GetAsync(uri);
Another solution is to use a StreamReader on your existing TCP connection, an example of that is in the question below. Although solution really depends on what your server it.
How reading messages from Server? (tcp)
If you are calling a web-service that uses soap/xml then use a web-service client ( add a Web Reference to your visual studio project )
Use an System.Net.Http.HttpClient or a System.Net.WebClient to download an xml file from a web-server.
No not try and decode encrypted web traffic using a TCP client.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
From some time now I'm trying to learn about Socketing programming in c#. I've been looking over many msdn, stackoverflow and codeproject projects, discussions and examples.
I rewrote them, I used debug and "step -in " in Visual Studio, I took it line by line and now I'm on "my little project." It is a mini - chat (console application). Let me describe the code and at the bottom I will give you my problems.
Server:
Main:
I've started a server, a TcpListener on ip 0.0.0.0 and port 8000.
I've created a thread on a method that accept my clients ( used 3 threads, this is one of them, the first ) and started it.
Method Accept Clients:
I've used a TcpClient to accept Tcp Clients from the TcpListener in a while(true).
I've got the stream out of that client and I've created a streamReader and a streamWriter over that stream.
I've started a thread, the second one, in which I've done the logic for writing.
And I've stared the 3rd thread in witch I've done the logic for the reading.
Here's the code:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace TcpServer
{
class TcpServer
{
static TcpListener tcpL;
static TcpClient tcpC;
static NetworkStream nStream;
static StreamWriter sW;
static StreamReader sR;
static List<TcpClient> lTcp;
static void Main(string[] args)
{
Console.WriteLine(" >> Server Started");
tcpL = new TcpListener(IPAddress.Parse("0.0.0.0"), 8000);
tcpL.Start();
Thread accClients = new Thread(acceptClients);
int counter = 0;
accClients.Start(counter);
Console.ReadLine();
}
private static void acceptClients(object obj)
{
while (true)
{
tcpC = tcpL.AcceptTcpClient();
Console.WriteLine(" >> Client Connected");
nStream = tcpC.GetStream();
sW = new StreamWriter(nStream);
sR = new StreamReader(nStream);
Console.WriteLine(" >> Data Transfer Established");
Thread thWrite = new Thread(doWriteing);
thWrite.Start(sW);
Thread thRead = new Thread(doReading);
thRead.Start(sR);
}
}
private static void doWriteing(object obj)
{
StreamWriter sW = (StreamWriter)obj;
while (true)
{
sW.WriteLine(Console.ReadLine());
sW.Flush();
}
}
private static void doReading(object obj)
{
StreamReader sR = (StreamReader)obj;
while (true)
{
string linie;
try
{
linie = sR.ReadLine();
Console.WriteLine(linie);
}
catch (Exception)
{
continue;
}
}
}
}
}
And the Client:
This one is quite simple.
Main:
I've connected the TcpClient on ip 127.0.0.1 and port 8000.
I've got the stream out of the TcpClient.
Created a StreamWriter and a StreamReader over that stream.
Started 2 threads for Writing and Reading.
Here's the code:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace TCPClient
{
class TCPClient
{
static TcpClient tcpC;
static NetworkStream nStream;
static void Main(string[] args)
{
Console.WriteLine(" >> Client Started");
tcpC = new TcpClient("127.0.0.1", 8000);
Console.WriteLine(" >> Client Connected");
nStream = tcpC.GetStream();
StreamWriter sW = new StreamWriter(nStream);
StreamReader sR = new StreamReader(nStream);
Thread thWrite = new Thread(doWriteing);
thWrite.Start(sW);
Thread thRead = new Thread(doReading);
thRead.Start(sR);
Console.ReadLine();
}
private static void doWriteing(object obj)
{
StreamWriter sW = (StreamWriter)obj;
while (true)
{
sW.WriteLine(Console.ReadLine());
sW.Flush();
}
}
private static void doReading(object obj)
{
StreamReader sR = (StreamReader)obj;
while (true)
{
string linie;
try
{
linie = sR.ReadLine();
Console.WriteLine(linie);
}
catch (Exception)
{
continue;
}
}
}
}
}
Now I have 3 big questions:
Why, or maybe "How", does the server send data to every thread( to only one thread at a time ) in the order they are created? Please explain this to me, I really want to understand the process. Here is a "sample"( it seems i can't post pictures ):
Serve* ( sending )
> >> Server Started
> >> Client Connected
> >> Data Transfer Established
> >> Client Connected
> >> Data Transfer Established
> >> Client Connected
> >> Data Transfer Established
.
1
2
3
4
5
6
Client 1 ( receiveing )
>> Client Started
>> Client Connected
1
4
Client 2 ( receiveing)
>> Client Started
>> Client Connected
2
5
Client 3 ( receiveing)
>> Client Started
>> Client Connected
3
6
How can I send the data received by the server to all clients ?
How can I store them ? What exactly to store ( and in what ) to be able to inform the server that this client id wants to send data to X client id. ( for example: client 1 wants to say "I was on the beach" to client 3 and "I was home" to client 2 )
/* I know there might appear many throws because I didn't programmed so defensively, but now I only want to learn and for me any exception that might appear can help. And I know that the first stream Flush doesn't arrive but in that case probably I've done something wrong, for that problem I'll be investigating. */
/* And important to mention: The Clients are chatting only with the server, they don't see what the others clients write. And the server receive the data in the correct order */
P.S. Please, if you take an interest in this problem, work with this code. I came here because I want to learn this things not because I search another "trick" or only to solve it.
I will try to answer the questions as best as I understand them:
Firstly you should properly add more debugging messages to your code, as this will greatly help you understand the process. Here is a pastebin where I have modified your code to include more messages so that you can better understand what read/write are doing.
Why, or maybe "How", does the server send data to every thread( to
only one thread at a time ) in the order they are created? Please
explain this to me, I really want to understand the process. Here is a
"sample"( it seems i can't post pictures ):
The server is not sending data to every thread. It is sending data to the Streams that are retrieved by the tcpC.GetStream(). In the acceptClients function, you get the network stream for that specific client (the one that connected). You then pass these to the new threads you create. Each read/write thread pair then has access to their own NetworkStream for working with the clients.
The reason you are properly confused, is because you overwrite tcpC and nStream with the values of other clients. The variables tcpC and nStream should really be a List. As for each client connected, there is a TcpClient and a NetworkStream.
In other words. On the server, for every client you have running there is 1 TcpClient, 1 NetworkStream and 2 Threads.
How can I send the data recived by the server to all clients ?
What you want to do is broadcast information received to all clients (like a chat program). To do this you will need a List<string> to act as a buffer. The means on your server in the doReading function you will read to a list (a buffer) that will store what you read from a client. You will then use the doWriteing function to write that list to clients. You will also need a way of making sure that the server sent to all clients the messages (not just to one of them).
client 1 wants to say "I was on the beach" to client 3
For this you will properly need a way of saying that in a command line format. Something like
SEND ID TEXT
Where ID is the client # you wish to send, and every after is the message. You can then also use something like BROADCAST TEXT for broadcasting to all clients.
Pastebin link again: http://pastebin.com/SBjc6tBF
When a client connects to the server, add the client to a collection. When the server receives data that it needs to pass to all other connected clients, iterate over the collection of clients and send them the data. You will need to check if the client is still connected. Broadcasting a message to all connected clients is easier than private messaging. You simply replay the message from one client to all clients as described above. For private messaging, clients will need to send commands to the server, which indicates a clients intentions. For example a simple command might be
SEND "Hello John" TO CLIENT 3
I've been looking around for the answer without luck. The program is a simple chat app that either listens or talks. The connection is established between the client and server, but when I send a message, the other does not seem to recieve it.
server waiting for connection
private void ListenForConnection(IPAddress ipAddress)
{
tcpListener = new TcpListener(ipAddress, portNumber);
tcpListener.Start();
client = tcpListener.AcceptTcpClient();
stream = client.GetStream();
stream.ReadTimeout = 200;
}
client connecting
private void EstablishConnection(IPAddress ipAddress)
{
client = new TcpClient();
client.Connect(ipAddress, portNumber);
stream = client.GetStream();
stream.ReadTimeout = 200;
}
client writing a message
public void SendMessage(String message)
{
StreamWriter networkWriter = new StreamWriter(stream);
networkWriter.Write(message);
networkWriter.Flush();
}
server reading a message
public String ListenForMessage()
{
String networkRead = String.Empty;
try
{
networkRead = new StreamReader(stream).ReadToEnd();
}
catch (Exception e) { }
return networkRead;
}
The send and recieve are identical for server and client. I intend to add error handling more when the messages are working.
I'm wondering that possibly there is an issue with my connection. Currently I am running 2 instances of the chat program on my machine, one server one client. The client connects at 127.0.0.1 (localhost) on port 8080 when the server is listening to port 8080. However the client does not connect at 192.168.1.100, which is my computer's actual ip, not sure if that might indicate something.
EDIT: adjusted the write and read to use stream writer and reader and flush
1.First of all , I will suggest you to make sure that your connection has been really established between your client and server.
2.Secondly, I will suggest you to flush your stream after you write, there are cache mechanism built in Stream, write to stream doesn't mean it will be send across the wire immediately.
3.It is a good way to learn networking in this way, but if you are creating commercial product, I will suggest you to look for some mature open source components.
I am trying to write a simple UDP program in C# which sends and receives data on localhost. I am a beginner in C# but much better at MATLAB so instead of writing the server and the client in C#, I decided to send data using C# and receive it in MATLAB.
I tried two approaches to send data. Using Socket class worked, but using UdpClient class failed.
Before running this code, I run the MATLAB code to set the callback function to print the received datagram.
Only one region is active in each run. I comment out the other one.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Net;
namespace udp1
{
class Program
{
const int port = 62745; //Chosen at random
static void Main(string[] args)
{
string str = "Hello World!";
byte[] sendBytes = Encoding.ASCII.GetBytes(str);
#region 1 Send data using socket class
Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), port);
sock.SendTo(sendBuff, ipEndPoint);
Console.ReadLine();
#endregion
#region 2 Send data using UdpClient class
UdpClient sendingClient = new UdpClient(port);
sendingClient.Send(sendBytes, sendBytes.Length);
#endregion
}
}
}
I am getting
Only one usage of each socket address (protocol/network address/port)
is normally permitted
error when I run the code in region 2.
However, when I run the code in region 1 everything works as I expect and I receive the data in MATLAB without any problems.
Here is my MATLAB code. I have used this code in other applications, so I highly doubt there is anything wrong with it.
fclose(instrfindall); %Close all udp objects
%UDP Configuration
udpConfig.ipAddress = '127.0.0.1';
udpConfig.portAddress = 62745;
udpObj = udp(udpConfig.ipAddress, udpConfig.portAddress, ...
'LocalPort', udpConfig.portAddress, ...
'ByteOrder', 'bigEndian');
set(udpObj, 'datagramTerminateMode', 'on');
set(udpObj, 'datagramReceivedFcn', {#cbDataReceived, udpObj});
fopen(udpObj);
And the callback function:
function cbDataReceived(hObj, eventdata, udpObj)
bytesAvailable = get(udpObj, 'BytesAvailable');
receivedDatagram = fread(udpObj, bytesAvailable);
disp(char(receivedDatagram));
end
So, why am I getting the error in UdpClient case and not getting it in Socket case? Is there a way to avoid that error?
I understand that you are using the same port for both MATLAB and C# on the same computer. Thus, operating system does not allow to open the same port from different applications.
UDP allows sending and receiving datagrams from different ports, so use different ports for different applications if both applications are running on the same computer.
UdpClient sendingClient = new UdpClient(62746); // Some different port to listen
sendingClient.Send(sendBytes, sendBytes.Length, ipEndPoint);