사용툴 : Unity3d (C#)
1. 소켓 연결
private bool _socket; ArrayList byteBufferList = new ArrayList(); ArrayList connectionList = new ArrayList(); try { // 소켓 연결 설정 (IP ADDRESS, PORT NUMBER, ...) IP 주소는 숫자와 and .(dot) 둘이 같이 넣어줘야함(ex : 192.168.0.38) _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); IPAddress remoteIPAddress = IPAddress.Parse(serverIP); IPEndPoint remoteEndPoint = new IPEndPoint(remoteIPAddress, portNumber); // 소켓 연결 함수 _socket.Connect(remoteEndPoint); } catch (Exception) { // IP ADDRESS, PORT NUMBER가 잘못 입력 되었을 경우 ... } // 소켓이 정상적으로 연결되었다면 connectionList에 담는다. connectionList.Add(_socket); byteBufferList.Add(new ArrayList());
2. 데이터 전송
// Remote Controller에 해당 데이터 버튼 생성 byte[] checkData = new byte[100]; checkData = System.Text.Encoding.UTF7.GetBytes("보낼데이터"); _socket.Send(checkData); // Example1 : Remote Controller의 버튼을 초기화 하고 싶을 때에는 "reset"을 보내준다. // byte[] checkData = new byte[100]; // checkData = System.Text.Encoding.UTF7.GetBytes("reset"); // _socket.Send(checkData); // Example2 : 만일 영상도 함께 보내는 경우라면 아래 코드를 통해 보내야함 // Message를 전송 할 때에는 영상을 잠시 보내지 않는다. //_isCheckWebcamPlay = false; //yield return new WaitForSeconds(0.1f); // byte[] checkData = new byte[100]; // checkData = System.Text.Encoding.UTF7.GetBytes("데이터보낸다"); // _socket.Send(checkData); // 종료 확인 메시지 전송 // checkData = SiCiUtil.EncodingString("end"); // _socket.Send(checkData); // yield return new WaitForSeconds(0.1f); // 정지되었던 영상 정상화 // if (_isWebcam) // { //_isCheckWebcamPlay = true; //StartCoroutine(SendCameraSecond(_cameraSendSpeed)); // }
3. 데이터 수신
if (null != _socket && true == _socket.Connected) { ArrayList con = new ArrayList(connectionList); Socket.Select(con, null, null, 1000); // 연결된 소켓들에 대하여 데이터를 읽어 옴 foreach (Socket soc in con) { ArrayList buf = (ArrayList)byteBufferList[connectionList.IndexOf(soc)]; // 실제 byte 배열을 받는 함수 (receiveBytes에 데이터가 저장되고 read변수에 길이가 저장된다.) int read = soc.Receive(receiveBytes); for (int i = 0; i < read; i++) buf.Add(receiveBytes[i]); // 전달받은 byte를 string으로 변환 string str = System.Text.Encoding.UTF7.GetString((byte[])buf.ToArray(typeof(byte))); Debug.Log("Received Message : " + str); if (str == "#reset#") { // 이벤트 받아오기 버튼이 눌러졌을 경우 여기로 옴 buf.Clear(); return; } else { // 누른 버튼의 번호가 전송 됨 (1 부터 시작) return; } } }
// 영상도 함께 사용 할 경우
4. 영상 정보 얻기
private string deviceName; WebCamTexture wct; private bool _isCheckWebcamPlay = false; private bool _isCheckWebcam = false; private bool _isWebcam = false; private float _cameraSendSpeed = 0.1f; // Webcam 얻어오는 부분 try { // WebCamTexture를 이용하여 연결된 device 목록을 가져온다. WebCamDevice[] devices = WebCamTexture.devices; deviceName = devices[0].name; // 만일 카메라가 여러개라면 전면 카메라를 선택한다. // 후면 카메라 선택하고 싶을 경우에는 아래 부분 주석 처리. // ---------------------------------------------------------- for (int i = 0; i < devices.Length; i++) { if (devices[i].isFrontFacing) deviceName = devices[i].name; } // ---------------------------------------------------------- // 카메라의 해상도 설정 // 넥서스7 기준으로 QCIF(176x144), QVGA(320x240), FULL HD(1280x768)만 설정 가능 // ex) 50x100 으로 해당 값을 설정하여도 QCIF로 나오게 된다. // 따라서 해상도를 낮추고 싶을 경우에는 따로 함수를 만들어서 사용 해야한다. wct = new WebCamTexture(deviceName, 1280, 768, 12); // 영상을 재생할 Plane을 찾아서 넣어준다. transform.FindChild("Plane").renderer.material.mainTexture = wct; wct.Play(); } catch (Exception) { // 에러 처리 return; } // 카메라 관련 변수 셋팅 _isCheckWebcamPlay = true; _isCheckWebcam = true; _isWebcam = true; // 소켓을 통해 영상을 보내줌 if (_isCheckWebcam) StartCoroutine(SendCameraSecond(_cameraSendSpeed));
5. 영상 전송
// 영상 전달 IEnumerator SendCameraSecond(float sendTime) { Debug.Log("SendCameraSecond"); // 영상이 시작한다는 뜻으로 #CameraStart# Message 전달 byte[] checkData = System.Text.Encoding.UTF7.GetBytes("#CameraStart#"); _socket.Send(checkData); yield return new WaitForSeconds(2f); while (_isCheckWebcamPlay) { SendCamera(); yield return new WaitForSeconds(sendTime); } } private void SendCamera() { try { // 카메라 영상을 받아옴 Color32[] cols = wct.GetPixels32(); // 소켓을 통해 전송 할 byte array (80x48x3) width : 80, height : 48, rgb 값 (alpha제외) byte[] bytes = new byte[11520]; // ex) 화질 축소하는 부분 // 처음부터 1280x768로 설정하고 화질을 낮춘 이유는 넥서스7에서 QCIF, QVGA로 설정 할 경우 // 화면이 확대되어 나오는 현상이 있어서 FULL HD 화질로 설정 후 줄이게 되었음 // 1280 / 16 = 80, 768 / 16 = 48 int idx = 0; for (int i = 0; i < 768; i = i + 16) { for (int j = 0; j < 1280; j = j + 16) { bytes[idx] = cols[i * 1280 + j].r; bytes[idx + 1] = cols[i * 1280 + j].g; bytes[idx + 2] = cols[i * 1280 + j].b; idx += 3; } } // Socket이 null이 아니라면 전송 if (_socket == null) ShutDown(); else _socket.Send(bytes); } catch (Exception) { // 오류 처리 } }
Sample Project 사용법
1.
2.
3.
4.
5.
6.
7.
8.