Search Unity

  1. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Question How can i make this TCP server in c#?

Discussion in 'Scripting' started by nikola20036, Apr 27, 2023.

  1. nikola20036

    nikola20036

    Joined:
    Feb 18, 2021
    Posts:
    8
    I want to make this Python script into a c#(unity) one.

    Python script:

    import socket

    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_socket.bind(('0.0.0.0', 2555))
    server_socket.listen()

    while True:
    client_socket, client_address = server_socket.accept()
    print(f"Connection from {client_address} established.")

    try:
    data = client_socket.recv(1024)
    while data:
    print(data.decode('utf-8'), end='')
    data = client_socket.recv(1024)
    finally:
    client_socket.close()


    This is my try at making it in c#(it doesn't work it just gets stuck at "Server is listening even if the client is trying to connect):
    Code (CSharp):
    1. using System;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using System.Net;
    5. using System.Net.Sockets;
    6. using System.Text;
    7. using System.Threading;
    8. using UnityEngine;
    9. public class TCPTestServer : MonoBehaviour {
    10.     #region private members
    11.     private TcpListener tcpListener;
    12.     private Thread tcpListenerThread;
    13.     private TcpClient connectedTcpClient;
    14.     #endregion
    15.        
    16.     void Start () {
    17.         tcpListenerThread = new Thread (new ThreadStart(ListenForIncommingRequests));
    18.         tcpListenerThread.IsBackground = true;
    19.         tcpListenerThread.Start();
    20.     }
    21.    
    22.     void Update () {
    23.    
    24.     }
    25.     private void ListenForIncommingRequests () {
    26.         try {
    27.             tcpListener = new TcpListener(IPAddress.Parse("0.0.0.0"), 2555);
    28.             tcpListener.Start();
    29.             Debug.Log("Server is listening");
    30.             Byte[] bytes = new Byte[1024];
    31.             while (true) {
    32.                 using (connectedTcpClient = tcpListener.AcceptTcpClient()) {
    33.                     using (NetworkStream stream = connectedTcpClient.GetStream()) {
    34.                         int length;
    35.                         while ((length = stream.Read(bytes, 0, bytes.Length)) != 0) {
    36.                             var incommingData = new byte[length];
    37.                             Array.Copy(bytes, 0, incommingData, 0, length);
    38.                             string clientMessage = Encoding.ASCII.GetString(incommingData);
    39.                             Debug.Log("client message received as: " + clientMessage);
    40.                         }      
    41.                     }
    42.                 }
    43.             }
    44.         }
    45.         catch (SocketException socketException) {          
    46.             Debug.Log("SocketException " + socketException.ToString());        
    47.         }    
    48.     }  
    49. }
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,298
    Nothing in Unity can loop like that, at least not on the main thread and without yielding.

    I'll leave it to the network gurus for how to actually do this. I suspect it would work if you fired it off from another thread and then marshaled responses back to your main thread with a mechanism like this:

    Delegate queue to marshal tasks from other threads to the main thread:

    https://forum.unity.com/threads/how...-everytime-it-is-called.1148354/#post-7370375
     
    nikola20036 likes this.
  3. dlorre

    dlorre

    Joined:
    Apr 12, 2020
    Posts:
    700
  4. orionsyndrome

    orionsyndrome

    Joined:
    May 4, 2014
    Posts:
    3,066
    Where is your socket?
    Do not use TcpListener, use a socket. It's pretty much the same as in Python.

    edit: oh, and what Kurt said applies first and foremost.

    Here's my old-ish code, I'm just copy/pasting.
    It's part of a full production code of some project of mine, maybe some things are obsolete or could be better.
    Code (csharp):
    1. using UnityEngine;
    2. using System;
    3. using System.Net;
    4. using System.Net.Sockets;
    5. using System.Collections;
    6.  
    7. public class SocketClient {
    8.  
    9.   public delegate void SocketCallback(byte[] data);
    10.   public delegate void SocketErrorHandler(int errorCode, string message);
    11.  
    12.   private Socket _socket;
    13.   private byte[] _recieveBuffer = new byte[8142];
    14.  
    15.   private SocketCallback _callback;
    16.   private SocketErrorHandler _errorHandler;
    17.  
    18.   public bool Open(string address, int port, SocketCallback callback, SocketErrorHandler errorHandler) {
    19.     bool success = true;
    20.     if(_socket == null) _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    21.  
    22.     try {
    23.       _socket.Connect(address, port);
    24.  
    25.     } catch(SocketException ex) {
    26.       success = false;
    27.       errorHandler(ex.ErrorCode, ex.Message);
    28.  
    29.     }
    30.  
    31.     if(success) {
    32.       _socket.BeginReceive(_recieveBuffer, 0, _recieveBuffer.Length, SocketFlags.None, new AsyncCallback(_receiveCallback), null);
    33.       _callback = callback;
    34.       _errorHandler = errorHandler;
    35.     }
    36.  
    37.     return success;
    38.   }
    39.  
    40.   public bool Close() {
    41.     bool success = true;
    42.  
    43.     try {
    44.       _socket.Close();
    45.       _socket = null;
    46.     } catch(Exception ex) {
    47.       success = false;
    48.       _errorHandler(-1, ex.Message);
    49.     }
    50.  
    51.     return success;
    52.   }
    53.  
    54.   private void _receiveCallback(IAsyncResult AR) {
    55.     // Check how much bytes are recieved and call EndRecieve to finalize handshake
    56.     int received = _socket.EndReceive(AR);
    57.  
    58.     if(received <= 0) return;
    59.  
    60.     // Copy the received data into new buffer, to avoid null bytes
    61.     byte[] recData = new byte[received];
    62.     Buffer.BlockCopy(_recieveBuffer, 0, recData, 0, received);
    63.  
    64.     // Process data here the way you want, all your bytes will be stored in recData
    65.     if(_callback != null) _callback(recData);
    66.  
    67.     // Start receiving again
    68.     _socket.BeginReceive(_recieveBuffer, 0, _recieveBuffer.Length,SocketFlags.None, new AsyncCallback(_receiveCallback), null);
    69.   }
    70.  
    71.   public void SendData(byte[] data) {
    72.     SocketAsyncEventArgs socketAsyncData = new SocketAsyncEventArgs();
    73.     socketAsyncData.SetBuffer(data, 0, data.Length);
    74.     _socket.SendAsync(socketAsyncData);
    75.   }
    76.  
    77. }
     
  5. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,848
    Your code kinda works, however you have several issues here.
    • The server / listener needs its own thread
    • Usually you will have a separate thread for each client, otherwise only a single client can connect. An alternative would be to use async receive methods which use a threadpool internally. Though it's a bit annoying to work with the async callbacks IMO.
    • The next huge problem is that TCP is a streaming protocol and not packet based. So whatever you do on your application layer has to split the streamed data however your custom application protocol works. For example HTTP which is text based uses "\r\n" as delimiter as well as a content length field in the header to determine when all data has arrived.
    I've made a simple example over here to create a standalone TCP server that just streams png images to all clients.
    Make sure you actually read my answer over here. I explained the general problem when working with TCP streams. Most application layer protocols usually use a binary format, at least for the "header" of "messages". Whatever that may be completely depends on your usecase and design.

    TcpListener and TcpClient are actually great wrappers around plain sockets as they wrap already most tcp specific stuff behind neat methods. When a listener accepts a client, you get back a TcpClient which wraps the specific client socket. Of course you have to manage the list of connected clients yourself and handle disconnects etc. Note that in my simple server clients don't send any data to the server and therefore I don't have a separate receiving thread for each client. Though usually you would need that when you want to do two way communication.

    Note that in my example the receive thread on the client side is that simple because the BinaryReader actually blocks when the underlying stream blocks. So it waits until enough data has arrived to read the requested number of bytes. In my case I only send a 4 byte integer as header which indicates the size of the image directly followed by the image data itself. This simply repeats like that. In most cases you want to define an actual header which may indicate a message type or something. Well as I said, designing your application level protocol is up to you. You have to make sure you send data that can actually be deciphered on the other side.
     
  6. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,848
    A long time ago I've written a small Delphi program (at least 18 years ago) which simply included a TCP server and a TCP client in one application. You could send text, hex characters or bytes (space separated). It even had the "feature" to connect the client and server and forward any data in both directions. So it could function as a "proxy". Though it printed all received data in the text boxes as hex strings (and as plain text in the bottom text box):
    upload_2023-4-27_16-53-39.png
    I haven't updated this crappy thing in the last 15 years but I always come back to using it for all kinds of tests or debugging purposes ^^. I was thinking about rewriting it in plain C# a couple of times now, but haven't found the time yet. Having such a tool can be really helpful when you want to test certain functionalities. Though applications like WireShark are also really helpful when debugging network issues. Of course when dealing with TLS / SSL encrypted connections things get more complicated.
     
    dlorre likes this.
  7. nikola20036

    nikola20036

    Joined:
    Feb 18, 2021
    Posts:
    8
    Hello! So as kurt said nothing can loop like that so i just moved everything to the Update method which kinda worked(lol).
    Code:
    Code (CSharp):
    1. using System;
    2.     using System.Collections;
    3.     using System.Collections.Generic;
    4.     using System.Net;
    5.     using System.Net.Sockets;
    6.     using System.Text;
    7.     using System.Threading;
    8.     using UnityEngine;
    9.     public class TCPTestServer : MonoBehaviour {
    10.         #region private members
    11.         private TcpListener tcpListener;
    12.         private Thread tcpListenerThread;
    13.         private TcpClient connectedTcpClient;
    14.         #endregion
    15.          
    16.         void Start () {
    17.             tcpListenerThread = new Thread (new ThreadStart(Update));
    18.             tcpListenerThread.IsBackground = true;
    19.             tcpListenerThread.Start();
    20.         }
    21.      
    22.         void Update () {
    23.             try {
    24.                 tcpListener = new TcpListener(IPAddress.Parse("0.0.0.0"), 2555);
    25.                 tcpListener.Start();
    26.                 Debug.Log("Server is listening");
    27.                 Byte[] bytes = new Byte[1024];
    28.                 while (true) {
    29.                     using (connectedTcpClient = tcpListener.AcceptTcpClient()) {
    30.                         using (NetworkStream stream = connectedTcpClient.GetStream()) {
    31.                             int length;
    32.                             while ((length = stream.Read(bytes, 0, bytes.Length)) != 0) {
    33.                                 var incommingData = new byte[length];
    34.                                 Array.Copy(bytes, 0, incommingData, 0, length);
    35.                                 string clientMessage = Encoding.ASCII.GetString(incommingData);
    36.                                 Debug.Log("client message received as: " + clientMessage);
    37.                             }    
    38.                         }
    39.                     }
    40.                 }
    41.             }
    42.             catch (SocketException socketException) {        
    43.                 Debug.Log("SocketException " + socketException.ToString());      
    44.             }
    45.         }
    46.     }
    The code crashes unity but if i make port 2555 busy it shows this in the console:
    upload_2023-4-27_19-10-45.png
    and it doesnt crash until i free the port(stop the other server that is using it). What do i do now?
     
  8. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,491
    Just cause you put it in Update doesn't change the fact that you have a while(true) loop that is looping forever blocking the frame.

    As was previously mentioned, this approach would require you putting it on its own thread. If you want to while(true) it forever, then it needs to be somewhere (a thread?) that doesn't impact other work in the program (the unity update/render loop).

    ...

    Also it was pointed out you aren't even using socket, you're using tcplistener.

    Here is the MSDN article on the System.Net.Sockets.Socket class:
    https://learn.microsoft.com/en-us/dotnet/api/system.net.sockets.socket?view=net-7.0

    In it is included an asynchronous way of approaching the problem which won't block the main update loop of unity.
     
    dlorre likes this.
  9. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,848
    I'm a bit confused by most answers here. He actually runs his server code on a separate thread, which does work just fine, at least when your target platform supports threads and sockets.

    I don't get this statement either. The TcpListener does wrap a socket. It's specialied for TCP sockets. The TcpListener as well as the TcpClient class even provides direct access to the underlying socket which you barely ever need. The code in the OP should actually work, though as I pointed out, you can't or shouldn't rely on "messages" to actually stay messages since TCP is an endless data stream. If you want to send messages, you have to implement an application level protocol in order to actually know when a whole message has been received and what fragments belong together.

    A TCP sever generally has two parts: The listening socket which accepts connection requests and starts new separate sockets for each client once the connection was successful and those client sockets which handle the actual data transfer. Those two concepts are only partially related. So you usually have a listening socket that just accepts clients in a loop. Each client can receive and send data on its own and may also need one or two threads when the blocking methods are used.

    The code in the OP would only accept a single client, since the listening socket would not accept any new client as long as the first client is connected. This may work in some rare usecases when you always only have a single client. Note that I ised the TcpListener / TcpClient classes in several usecases. I've even implemented my own websocket server with it. After all the TcpListener is just a wrapper around on ordinary socket.
     
    orionsyndrome likes this.
  10. orionsyndrome

    orionsyndrome

    Joined:
    May 4, 2014
    Posts:
    3,066
    Sure, you're right, my example doesn't deal with continuous streams and I haven't dealt with a TcpListener before. At least I didn't have such a use case. With my code a stream would be snipped after exactly 8192 bytes and served to a callback. Probably.

    I didn't pay any proper attention, and now that you mentioned it, yes, his example is a continuous stream. I only meant only to illustrate the basic implementation because I assumed it was the standard message ping pong.

    This btw worked flawlessly on Android. Obviously I had a layer above this SocketClient with state logic, which was used to arm and control the client, but nothing too complicated.

    Great explanation as always, btw, thanks.

    Oops. I just blindly followed Kurt's sherlocking. I think I should get some sleep.

    @dlorre sry for all this confusion, I'm guessing you're like traumatized from gaslighting :D
     
    Last edited: Apr 28, 2023
    Bunny83 likes this.
  11. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,491
    I only read the code in the most recent post which had it in Update... which... not good.

    Not only that it was a thread that started the method Update. So technically they would have been starting their tcplistener over and over and over and over every frame (if those frames could have been gotten to if not for the blocking) AS WELL as running one on the thread.
     
  12. orionsyndrome

    orionsyndrome

    Joined:
    May 4, 2014
    Posts:
    3,066
    Yeah well.
    But it's in a
    using
    block so at least no leaks! :)
     
  13. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,491
  14. nikola20036

    nikola20036

    Joined:
    Feb 18, 2021
    Posts:
    8
    it worked on Android?? I'm so confused.

    Alright, I'm going to put it in a separate function.

    to be honest this confuses me so much...

    Is there something else i can do?
     
  15. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,848
    Well, this thread got really sidetracked at times. You could start with what your actual issues are and it would probably be a good idea to tell us what you want to achieve in the end. I just took your script from the first post, put it in my test project as it is without any changes. I slapped it onto an empty gameobject in the scene and hit play. I used by TCP client app I already mentioned and connected to that port. I can send text and Unity receives it. So it does what you would expect. Though I already pointed out some potential issues, expecially when data is actually send over the internet or a network with actual latency, you can not rely that what you send out as one chunk would be received as one chunk.
    upload_2023-4-28_16-1-29.png

    Your original script also has other issues. You really should make sure to properly terminate your thread and also close the socket once you stop your application. Currently (and I have actually tried this) when you stop playmode, your thread will keep running and I can still send text to socket and it still produces debug logs in the console. Even though I'm back in edit mode. That's because you started a new background thread and Unity is not responsible for that. That thread may die forcefully when Unity performs a domain reload, but that's not how you should handle system resources.

    So if you need actual help with "something", tell us what your problem is. We don't know what client you try to connect to your server.
     
  16. orionsyndrome

    orionsyndrome

    Joined:
    May 4, 2014
    Posts:
    3,066
    Yes. Why is that confusing? TCP/IP is a standard web protocol and Unity is a cross-platform solution. The same solution also worked for WebGL.
     
  17. nikola20036

    nikola20036

    Joined:
    Feb 18, 2021
    Posts:
    8
    i have no idea how you even launched it. when i launch it, unity just freezes. I modified the code so that it closes the thread.

    Here is my code:

    Code (CSharp):
    1. using System;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using System.Net;
    5. using System.Net.Sockets;
    6. using System.Text;
    7. using System.Threading;
    8. using UnityEngine;
    9. public class TCPTestServer: MonoBehaviour {
    10.     #region private members
    11.     private TcpListener tcpListener;
    12.     private Thread tcpListenerThread;
    13.     private TcpClient connectedTcpClient;
    14.     #endregion
    15. private bool isRunning = true;
    16.  
    17. void Start () {
    18.     tcpListenerThread = new Thread (new ThreadStart(Update));
    19.     tcpListenerThread.IsBackground = true;
    20.     tcpListenerThread.Start();
    21. }
    22.  
    23. void Update () {
    24.     if (!isRunning) {
    25.         return;
    26.     }
    27.     try {
    28.         tcpListener = new TcpListener(IPAddress.Parse("0.0.0.0"), 2555);
    29.         tcpListener.Start();
    30.         Debug.Log("Server is listening");
    31.         Byte[] bytes = new Byte[1024];
    32.         while (true) {
    33.             using (connectedTcpClient = tcpListener.AcceptTcpClient()) {
    34.                 using (NetworkStream stream = connectedTcpClient.GetStream()) {
    35.                     int length;
    36.                     while ((length = stream.Read(bytes, 0, bytes.Length)) != 0) {
    37.                         var incommingData = new byte[length];
    38.                         Array.Copy(bytes, 0, incommingData, 0, length);
    39.                         string clientMessage = Encoding.ASCII.GetString(incommingData);
    40.                         Debug.Log("client message received as: " + clientMessage);
    41.                     }
    42.                 }
    43.             }
    44.         }
    45.     }
    46.     catch (SocketException socketException) {    
    47.         Debug.Log("SocketException " + socketException.ToString());  
    48.     }
    49. }
    50.  
    51. void OnApplicationQuit() {
    52.     isRunning = false;
    53.     tcpListenerThread.Join();
    54. }
    55. }
    i have no idea how you even managed to run it. i will try to reinstall unity
     
  18. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,848
    I clearly said
    The code you just posted and also the code you posted in post #7 makes no sense as it was already pointed out several times. You can not and MUST not use the Update callback for this. Again, I used the original code from the FIRST post. There you have a separate method called "ListenForIncommingRequests" which you actually run on a separate thread which handles all the networking stuff.

    This:
    Code (CSharp):
    1. void OnApplicationQuit() {
    2.     isRunning = false;
    3.     tcpListenerThread.Join();
    4. }
    is not enough. You set the isRunning flag to false, which is good. However your socket is actually blocking your thread. So unless data arrives at the socket, the thread would never "unblock" in order to reach the while condition again. When you just join with the thread, you would just block your main thread until your network thread finishes.

    At the moment you only hold your listener and client sockets exclusively inside your thread method. So there's no way to actually access them from outside. You should close the sockets (the listening socket by calling Stop on the TcpListener as well as the client socket by calling Close on the TcpClient). When you close the socket the blocking Read call will return with a count of 0 which indicates that the socket has been closed. As a safety net you can call Abore on the thread which will deliberately throw a ThreadAbortException inside that thread which will forcefully terminate the thread. However this should only be a fallback solution. Closing your sockets properly and ending your thread normally should be the preferred solution.

    Those are all absolute fundamental basics of those networking classes. Again we still don't know what you want to achieve with this.
     
  19. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,848
    Uhm, no ^^ WebGL does not have any socket support. You can use WebSockets which are something different since they build on top of usual HTTP connections. In a WebGL build you can not use any classes which use "normal" sockets for security reasons. The browsers don't support that. Otherwise a website could start a listening socket and essentially run a server in your browser. A browser can only act as a client and is subject to the Same-origin policy on top of that. CORS can loosen that restriction a bit. Though inside a browser you are quite limited when it comes to networking.
     
  20. nikola20036

    nikola20036

    Joined:
    Feb 18, 2021
    Posts:
    8
    Hi! so... the first script started working... no idea why... but it works! so thanks to everyone!
     
  21. orionsyndrome

    orionsyndrome

    Joined:
    May 4, 2014
    Posts:
    3,066
    It was quite some time ago and details are now lost to me, but trust me, I managed to do it, otherwise I'd lose a pretty big freelance project. Because that didn't happen, and this project relied on sockets for back end communication, I'm absolutely sure it worked flawlessly.

    Now if what you meant is security per se, for that I might've had to make a crossdomain file or something like that, because I had full access to the hosting server. I only remember that in the midst of deployment Google changed its policy on native plugins and this was a huge PITA.
     
    Bunny83 likes this.
  22. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,848
    :D I can guarantee you that it has never worked.

    Maybe you think about the good old UnityWebPlayer? Well that's not WebGL as it is a native plugin that could do whatever it wanted and of course could use sockets. Though that plugin needs to be installed on the client machine. This is still possible to some degree. You can create browser extensions which can communicate with locally installed applications. So that way you could do whatever you want. However those "extensions" and programs need to be installed manually on the client, so the risk is in the clients hands.

    Yes, the WebPlayer allowed Socket connections, but also only client connections and only when a socket policy was provided on the target server. Listening sockets were not supported with the exception of RakNet. I played around a lot with RakNet back then (you could even host a game inside the browser plugin which was quite neat and with the public master server you could even have clients host games, others can join without the need of an actual server anywhere).
     
    orionsyndrome likes this.
  23. orionsyndrome

    orionsyndrome

    Joined:
    May 4, 2014
    Posts:
    3,066
    It's a single binary with unity3d extension, so that's what I meant, my mistake. Thanks for clearing that up.
     
  24. nikola20036

    nikola20036

    Joined:
    Feb 18, 2021
    Posts:
    8
    So I still have a problem. I know why it didn't work when I started. I tried to connect and send packets using my phone. which didn't work, but when I tried the EXACT same code on my local device(my computer) it worked. im sure my phone is connected to the wifi network. i also tried to send packets from a old laptop that i have that didnt work either. it connects only if i try to connect from the same device.
     
  25. dlorre

    dlorre

    Joined:
    Apr 12, 2020
    Posts:
    700
    orionsyndrome and Bunny83 like this.
  26. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,848
    Well, what does your client code actually look like and what IP do you connect to? You do know that the address 127.0.0.1 always refers to your own computer / device.

    You still haven't expanded on what you actually want to achieve. Originally you said you have "a problem" but didn't really say what problem. I tried your original code and it works. Now you seem to have a different problem but again you haven't added any details about your problem. You may want to start showing what your client code looks like. If you want to connect inside a local area network, make sure you actually use the correct IP address and as @dlorre said, make sure the firewall isn't blocking your connection.

    Of course you can't really connect from the internet unless you have setup a port-forwarding rule in your router. And even then depending on the router, local loopbacks are often blocked by routers. So others on the internet can connect, but you can't by using the external IP from inside the same NAT. That makes testing a bit more complicated.

    Please, if you want help and answers, be more specific with your questions.

    ps: While your original code kinda works, keep in mind the points we have mentioned. Closing the sockets is important as you can only bind a port once to the same endpoint. If there's still a lingering socket open it would prevent another application / instance to open / bind the port.
     
  27. nikola20036

    nikola20036

    Joined:
    Feb 18, 2021
    Posts:
    8
    Code (CSharp):
    1.  
    2. import socket
    3. client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    4. client_socket.connect("192.168.1.102", 2555)
    5. msg = "Hello World!"
    6. client_socket.sendall(msg.encode())
    7. response = client_socket.recv(1024)
    8.  
    This is my client-side code. I don't think it's a firewall issue since my Python version of the server works fine with every device I have. also, I don't want to port forward and i don't need to sense both devices are connected to the same network.
    Im going to fix the socket closing issue later on. im just going to change the port every time for now. i want to fix the connection issue for now.
     
  28. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,848
    That's kinda irrelevant. The Python interpreter is a standalone application. The firewall works on an application-basis. So when the python application is allowed, it generally works.

    We can't really help you with your debugging on your devices. Just make sure the address you use is the actual address of your server.

    Note: I've written my own DNS server as a plain C# standalone application. It actually runs on my raspberry pi with mono and is reachable from the internet. I also use the TcpListener for the TCP part of the server (DNS usually uses UDP).

    In order to debug your issues, you can do various things. First of all try running "netstat" with admin privileges (press Win+R, enter "cmd" and hold CTRL + SHIFT when pressing enter / clicking on ok to start cmd with admin privileges). Now you can enter
    netstat -a -b -o -n -p tcp
    . This should list all (-a) connections, including the application (-b) and process id (-o). It makes sure addresses and ports are in numerical format (-n) and only shows tcp connections (-p tcp). It's the "-b" and "-o" that require admin privileges. That way you can see if a different application may be blocking a certain port. Note that application name actually follows the connection.

    You should also check the list of applications in the firewall settings. Just type "wf.msc" in the cmd window to open the firewall settings. When you're testing inside the Unity editor, make sure the Unity.exe doesn't have any blocking entries in any of the lists. If you're running your application as a standalone application, look for that application.

    It may be a bit overkill as using it can be a bit challenging, but installing WireShark or some other network logging / packet capture application could also help finding the issue. Of course wrapping all your code in a try catch and properly displaying any exception that may be thrown can also help. Maybe your thread is terminated due to an exception. Those do not necessarily show up in the console by default.
     
  29. dlorre

    dlorre

    Joined:
    Apr 12, 2020
    Posts:
    700
    Bunny83 likes this.