[Node.js] 2022/05/17 : Node_Socket2, UDP, TCP
10)board.js 파일에 초기화를 위한 코드를 추가 - $(function(){여기에 추가})
//색상 선택 select에 추가할 내용
var color_map = [
{'value':'white', 'name':'하얀색'},
{'value':'red', 'name':'빨간색'},
{'value':'orange', 'name':'주황색'},
{'value':'yellow', 'name':'노란색'},
{'value':'blue', 'name':'파랑색'},
{'value':'black', 'name':'검은색'},
]
//select 에 설정
for(var key in color_map){
$('#pen_color').append('<option value=' + color_map[key].value +
'>' + color_map[key].name + '</option>')
}
//두께 선택 select 설정
for(var i=1; i<16; i++){
$('#pen_width').append('<option value=' + i + '>'
+ i + '</option>');
}
11)board.js 파일의 shape 객체에 select 의 값이 변경되었을 때 호출될 함수를 추가
change:function(){
var color = $('#pen_color option:selected').val();
var width = $('#pen_width option:selected').val();
shape.setShape(color, width);
},
12)board.js 파일에 select 값이 변경될 때 호출할 함수를 설정 - $(function(){여기에 추가})
//select 에 이벤트 연결
$('select').bind('change', shape.change);
13)index.js 파일에 소켓 서버 설정 코드를 추가
const io = require('socket.io')(server)
14)websocket.html 파일에 socket.io.js 파일을 사용할 수 있도록 링크를 추가
<script src="/socket.io/socket.io.js"></script>
15)board.js 파일에 전역 변수 선언
var socket;
16)board.js 파일에 소켓 생성 코드를 추가 - $(function(){여기에 추가})
socket = io.connect('http://' + window.location.host);
17)board.js 파일에 msg 객체 생성
var msg = {
line:{
send:function(type, x, y){
socket.emit('linesend', {
'type':type,
'x':x,
'y':y,
'color':shape.color,
'width': shape.width
})
}
}
}
18)board.js 파일의 이벤트 처리 함수에 메시지를 전송하는 코드를 추가
var draw = {
drawing:null,
start:function(e){
ctx.beginPath();
ctx.moveTo(e.pageX, e.pageY);
this.drawing = true;
//console.log('마우스 버튼 누름');
msg.line.send('start', e.pageX, e.pageY);
},
move:function(e){
if(this.drawing){
ctx.lineTo(e.pageX, e.pageY);
ctx.stroke();
//console.log('마우스 움직임')
msg.line.send('move', e.pageX, e.pageY);
}
},
end:function(e){
this.drawing = false;
//console.log('마우스에서 손을 뗌')
msg.line.send('end');
},
clear:function(){
ctx.clearRect(0, 0, cv.width, cv.height);
msg.line.send('clear');
}
}
19)socket.js 파일에 메세지를 받았을 때 메시지를 전송하는 코드를 작성
//클라이언트에서 linesend 라는 이벤트가 발생하면
//연결된 모든 클라이언트에게 linesend_toclient 이벤트를 발생시킴
socket.on('linesend', function(data){
socket.broadcast.emit('linesend_toclient', data);
});
20)board.js 파일에 linesend_toclient 이벤트가 온 경우 수행할 코드를 작성
//소켓에서 linesend_toclient 이벤트가 발생했을 때 처리
socket.on('linesend_toclient', function(data){
draw.drawfromServer(data)
});
21)board.js 파일의 draw 객체에 drawfromServer 함수를 추가
drawfromServer:function(data){
if(data.type=='start'){
ctx.beginPath();
ctx.moveTo(data.x, data.y);
ctx.strokeStyle = data.color;
ctx.lineWidth = data.width;
}
if(data.type=='move'){
ctx.lineTo(data.x, data.y);
ctx.stroke();
}
if(data.type=='end'){
}
if(data.type=='clear'){
ctx.clearRect(0,0, cv.width, cv.height);
shape.setShape();
}
8.Node 의 Socket 프로그래밍
=>TCP 와 UDP 통신 모두 가능
1)TCP
=>연결형 프로토콜을 이용한 통신
=>요청하는 쪽에서 서버에게 요청을 하면 서버는 클라이언트에게 메타 데이터(데이터에 대한 정보)를 전송을 하고 클라이언트는 이 메타 데이터를 읽고 전송 가능 여부 와 데이터에 대한 정보를 파악해서 서버에게 실제 데이터 전송을 요청을 합니다.
서버는 실제 데이터를 전송하고 전송받은 쪽에서는 이에 대한 응답을 합니다.
=>신뢰성이 높은 통신 방식이지만 실제 데이터 이외에도 다른 데이터를 많이 전송하기 때문에 효율은 떨어질 수 있습니다.
=>대부분의 통신은 TCP 방식
2)UDP
=>비 연결형 통신으로 일방적으로 데이터를 전송하고 종료하는 방식
=>신뢰성이 낮지만(제대로 전송이 이루어졌는지 알 수 없음) 효율이 좋습니다.
=>DNS(Domain Name Service), APNS(Apple Push Notification Service), FCM(Google 의 Firebase Cloud Messaging) 등은 UDP 입니다.
9.Java 와 Node 간의 UDP 통신
1)Java 프로젝트를 생성해서 main을 가진 클래스를 생성
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class UDPServer {
public static void main(String[] args) {
try {
//UDP 소켓 클래스 생성
DatagramSocket dsoc = new DatagramSocket(4445);
//데이터를 저장하기 위한 바이트 배열 생성
byte [] data = new byte[65536];
while(true) {
System.out.println("받을 준비 완료");
//데이터를 전송받기 위한 준비가 완료 됨 - 데이터를 전송받아야 다음으로 넘어감
DatagramPacket dp = new DatagramPacket(data, data.length);
dsoc.receive(dp);
//보낸 곳 주소 확인
System.out.println("보낸 곳:" + dp.getAddress().getHostAddress());
//전송 받은 데이터 확인
String utf8String =
new String(new String(dp.getData()).trim().getBytes("UTF-8"));
System.out.println("받은 메시지:" + utf8String);
String msg = "자바에서 보낸 메시지";
//보낸 곳의 주소를 저장
InetAddress address = dp.getAddress();
int port = dp.getPort();
//UDP로 전송할 데이터 생성
dp = new DatagramPacket(msg.getBytes(), msg.getBytes().length,
address, port);
//데이터 전송
dsoc.send(dp);
}
}catch(Exception e) {
System.out.println("소켓 통신 에러");
System.out.println(e.getLocalizedMessage());
}
}
}
2)node 프로젝트에 udp.js 파일을 생성하고 작성
var http = require('http');
//UDP 통신을 위한 객체 생성
var client = require('dgram').createSocket('udp4');
var message = '보낼 데이터';
//메시지를 받았을 때 수행할 내용
client.on('message', function(msg, rinfo){
message = msg;
})
//에러가 발생했을 때 수행할 내용
client.on('error', function(err){
console.log('에러:', err);
})
http.createServer((req, res) => {
var data = new Buffer('Hello World');
client.send(data, 0, data.length, 4445, 'localhost');
res.writeHead(200, {
'Content-Type':'text/plain'
})
res.end(message);
}).listen(1338, '127.0.0.1');
console.log('Server 구동 중');
3)서로 다른 프로그래밍 언어 간에 문자열을 주고 받을 때는 인코딩에 주의를 해야 합니다.
문자열을 생성할 때 인코딩을 맞추어서 생성해야 합니다.
10.Node 와 Java 간의 TCP 통신
1)Java Project 에 클래스를 추가하고 작성한 후 실행
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
public class TCPServer {
public static void main(String[] args) {
//클라이언트의 접속을 처리하기 위한 소켓
ServerSocket ss = null;
//클라이언트 와 통신을 하기 위한 소켓
Socket socket = null;
try {
//서버 소켓을 생성
ss = new ServerSocket(9999);
while(true) {
System.out.println("서버 대기 중");
//클라이언트의 접속 대기
socket = ss.accept();
//접속자 정보 확인
System.out.println("접속자 정보:" + socket.toString());
//클라이언트가 전송한 정보 확인
BufferedReader in = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
//한 줄 읽기
String str = in.readLine();
System.out.println("전송된 내용:" + str);
in.close();
socket.close();
}
}catch(Exception e) {
System.out.println("소켓 통신 에러");
System.out.println(e.getLocalizedMessage());
}
}
}
2)node 프로젝트에 tcp.js 파일을 추가하고 작성
var http = require('http');
//TCP 통신을 위한 객체 생성
var client = require('net').Socket();
var fromServer = '';
//서버에 접속
client.connect(9999, function(){
console.log("서버에 접속 성공");
})
//서버에서 데이터가 전송된 경우
client.on('data', function(data){
console.log("받은 데이터:", data);
fromServer = data;
})
//연결이 해제된 경우
client.on('close', function(){
console.log('연결 해제');
client.destroy();
})
http.createServer((req, res) => {
client.write('안녕하세요 반갑습니다.', function(){
console.log('보내기 성공');
});
res.writeHead(200, {
'Content-Type':'text/plain; charset=utf-8'
})
res.end(fromServer);
}).listen(1338, '127.0.0.1');
console.log('Server 구동 중');