[Unity] C# & Python 소켓 TCP 통신

2021. 8. 10. 21:26

python 서버에서 데이터를 송신하고 unity에서 수신하는 tcp에서 구현하게 되었다. 사실 tcp를 처음해서 많이 헤맸고, 일반 C#과 좀 다를 수도 있기때문에 내가 성공한 방법을 그냥 기록겸... 뭔가 인터넷에 내 입맛에 딱맞는 해결책이 없어서 이곳저곳 참고했고, 내 코드가 정답은 아니다. 

 

무엇보다, 이 글은 tcp에 대한 설명은 생략한다... 나말고도 설명이 많이 잘 되어있음..!!!


파이썬 서버 -> 유니티 c# 클라이언트
서버에서 2초에 한번씩 데이터 전송


Python server

import socket
import time
from datetime import datetime

HOST = '127.0.0.1' 
PORT = 8000       

server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

server_socket.bind((HOST, PORT))

server_socket.listen()

client_socket, addr = server_socket.accept()

print('Connected by', addr)

k = 0

while True:
    
    msg = "hello world " + str(k)
    client_socket.sendall(msg.encode())
    print('send 완료 '+ str(k) )
    k += 1
    time.sleep(2)
    
    '''
    무한 루프를 돌면서 2초에 한번씩 데이터를 송신함.
    만약 종료 조건을 넣고 싶다면 여기에 넣으면 됨
    '''

client_socket.close()
server_socket.close()

디테일 한 설명을 보고 싶으면 이쪽에서 확인하면 된다. 

내코드에서는 서버는 데이터 송신만 한다. 수신을 위해서는 별다른 처리가 필요하다.

 

Unity C# Client

using System.Collections;
using System.Collections.Generic;
using System.Net.Sockets;
using UnityEngine;
using System.Text;
using System;
using System.IO;
using System.Runtime.InteropServices;

public class TCPManager : MonoBehaviour
{
    TcpClient client;
    string serverIP = "127.0.0.1";
    int port = 8000;
    byte[] receivedBuffer;
    StreamReader reader;
    bool socketReady = false;
    NetworkStream stream;


    // Start is called before the first frame update
    void Start()
    {
       CheckReceive();
    }

    // Update is called once per frame
    void Update()
    {
        
        if(socketReady)
        {
            
            
            if (stream.DataAvailable)
            {
                receivedBuffer = new byte[100];
                stream.Read(receivedBuffer, 0, receivedBuffer.Length); // stream에 있던 바이트배열 내려서 새로 선언한 바이트배열에 넣기
                string msg = Encoding.UTF8.GetString(receivedBuffer, 0, receivedBuffer.Length); // byte[] to string
                Debug.Log(msg);
            }
            
        }
    }

    void CheckReceive()
    {
        if (socketReady) return;
        try
        {
            client = new TcpClient(serverIP, port);

            if (client.Connected)
            {                
                stream = client.GetStream();
                Debug.Log("Connect Success");
                socketReady = true;
            }
            
        }
        catch (Exception e)
        {
            Debug.Log("On client connect exception " + e);
        }

    }

    void OnApplicationQuit()
    {
        CloseSocket();
    }

    void CloseSocket()
    {
        if (!socketReady) return;

        reader.Close();
        client.Close();
        socketReady = false;
    }

}

서버와 한번 연결 후 업데이트에서 데이터를 수신한다. (이럴경우가 있을진 모르겠지만 Start에서 CheckReceive를 호출해 주면 최초 한번만 실행하기 때문에, Update에서 조건문으로 호출 컨트롤 해줘도 괜찮다)

나는 데이터 수신 부분만 있는데, 데이터 송신 부분은 따로 추가해주면 양쪽으로 통신이 가능하다.

사실 다른 블로그에서 StreamReader 라는 객체 사용하는 것을 봤는데 나는 이걸 업데이트에서 호출해 주니까 왜인지 서버가 죽을때까지 유니티가 뻗어버리고 서버를 꺼야지 그제서야 한번에 여태 수신한 문자열을 뱉었다.... 그래서 버퍼로 받는 방식으로 바꿈. 사실 아직 tcp가 낯설어서... 유니티에서 새로 공부하게 된 분야라 정리해둔다. 포톤도 열심히 해야지.. 여태 의외로 통신을 하나도 제대로 못하고 있음...^ㅅT


서버와 클라이언트 결과



코드 참고 :
https://goraniunity2d.blogspot.com/2020/12/tcp.html

 

유니티 C# TCP 소켓통신으로 채팅하기

Chat.cs 소스입니다 using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class Chat : Mono...

goraniunity2d.blogspot.com

https://webnautes.tistory.com/1381

 

파이썬 소켓 프로그래밍 - 클라이언트 / 서버 예제

파이썬에서 소켓을 사용한 TCP 서버/클라이언트 예제에 대해 다룹니다. 클라이언트가 서버에 접속하여 통신이 시작되는 방식입니다.  1. TCP 소켓      2. 간단한 에코 서버, 클라이언트 예제  

webnautes.tistory.com