일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- LeetCode
- xcrun: error: invalid active developer path
- 스프링부트테스트
- Medium
- springboot
- mysql executequery error
- statement.executequery() cannot issue statements that do not produce result sets.
- log error
- java 11
- java version
- JUnit
- Java 1.8
- aws
- springboottest
- OpenFeign
- AWS CLI
- java 버전 변경
- yum install java
- No tests found for given includes
- parse
- java 여러개 버전
- easy
- java 1.8 11
- error
- mac os git error
- ssl이란?
- xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools)
- java
- ssl프로토콜확인
- tls프로토콜확인
- Today
- Total
쩨이엠 개발 블로그
[ TCP ] TCP Server 만들기 본문
TCP 프로토콜 통신을 위해 TCP Server를 만들어보기로 한다
Client에서 통신을 보내면 Server에서 받도록 프로젝트를 만들어보기로 한다
TCP Client --> TCP Server
개발환경
- Spring Boot 2.3.4.RELEASE
- Gradle 7.0
- Java 11
Package
build.gradle
plugins {
id 'java'
id 'org.springframework.boot' version '2.3.4.RELEASE'
id 'io.spring.dependency-management' version '1.0.10.RELEASE'
}
group 'com.test.iot'
version '1.0-SNAPSHOT'
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation 'org.springframework.boot:spring-boot-starter-integration'
implementation 'org.springframework.integration:spring-integration-ip'
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'
annotationProcessor 'org.projectlombok:lombok'
}
TCP 통신을 위한 dependency들을 넣어준다
lombok은 compile과 annotation으로 넣어준다
application.yml
tcp:
server:
port: 8092
TCP 통신할 포트를 적어준다
이는 Config파일에서 쓰일 예정
TCPServerProperties.java
package com.test.iot.config;
import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties("tcp.server")
@Getter
@Setter
public class TcpServerProperties {
int port;
}
ConfigurationProperties에서 prefix로 tcp.server를 가져오면 application.yml의 port인 8092가 TCPServerProperties.port의 값에 들어간다
TcpServerConfig.java
@Configuration
@EnableIntegration
@EnableConfigurationProperties(TcpServerProperties.class)
public class TcpServerConfig {
@Bean
public CustomTcpSerializer serializer() {
return new CustomTcpSerializer();
}
@Bean
public AbstractServerConnectionFactory connectionFactory(TcpServerProperties tcpServerProperties, CustomTcpSerializer serializer) {
TcpNioServerConnectionFactory connectionFactory = new TcpNioServerConnectionFactory(tcpServerProperties.getPort());
connectionFactory.setSerializer(serializer);
connectionFactory.setDeserializer(serializer);
connectionFactory.setSingleUse(true);
return connectionFactory;
}
@Bean
public MessageChannel inboundChannel() {
return new DirectChannel();
}
@Bean
public MessageChannel replyChannel() {
return new DirectChannel();
}
@Bean
public TcpInboundGateway inboundGateway(AbstractServerConnectionFactory connectionFactory, MessageChannel inboundChannel, MessageChannel replyChannel) {
TcpInboundGateway tcpInboundGateway = new TcpInboundGateway();
tcpInboundGateway.setConnectionFactory(connectionFactory);
tcpInboundGateway.setRequestChannel(inboundChannel);
tcpInboundGateway.setReplyChannel(replyChannel);
return tcpInboundGateway;
}
}
TCP Properties(port)와 bean등록을 해준다
TcpServerEndpoint.java
@MessageEndpoint
public class TcpServerEndpoint {
private final MessageService messageService;
public TcpServerEndpoint(MessageService messageService) {
this.messageService = messageService;
}
@ServiceActivator(inputChannel = "inboundChannel", async = "true")
public byte[] process(byte[] message) {
return messageService.processMessage(message);
}
}
TCP Endpoint를 지정해준다 inputChannel은 bean등록되어있는 것과 같은 이름으로 넣어준다
CustomTcpSerializer.java
public class CustomTcpSerializer extends AbstractPooledBufferByteArraySerializer {
public static final CustomTcpSerializer INSTANCE = new CustomTcpSerializer();
public static final int STX = 0x02;
public static final int ETX = 0x03;
@Override
public byte[] doDeserialize(InputStream inputStream, byte[] buffer) throws IOException {
int bite = inputStream.read();
if (bite < 0) {
throw new SoftEndOfStreamException("Stream closed between payloads");
}
buffer[0] = (byte) bite;
int length = inputStream.read();
if (length < 0) {
throw new SoftEndOfStreamException("Stream closed between payloads");
}
buffer[1] = (byte) length;
int n = 2;
try {
if (bite != STX) {
throw new MessageMappingException("Expected STX to begin message");
}
while (length != n) {
bite = inputStream.read();
checkClosure(bite);
buffer[n++] = (byte) bite;
if (n >= getMaxMessageSize()) {
throw new IOException("ETX not found before max message length: " + getMaxMessageSize());
}
}
if (bite != ETX) {
throw new MessageMappingException("Expected ETX to end message");
}
return copyToSizedArray(buffer, n);
} catch (IOException e) {
publishEvent(e, buffer, n);
throw e;
} catch (RuntimeException e) {
publishEvent(e, buffer, n);
throw e;
}
}
@Override
public void serialize(byte[] bytes, OutputStream outputStream) throws IOException {
outputStream.write(bytes);
}
}
MessageService로 넘기기 전에 inputStream을 읽어와야한다
TCP 통신에서 STX(Start of Text)와 ETX(End of Text) 사이에 있는 메세지를 array로 넘길 예정이다
inputStream.read()로 한 개씩 읽어온다(이건 받는 규칙마다 다름)
MessageService.java
@Slf4j
@RequiredArgsConstructor
@Service
public class MessageService {
private static final byte[] DEFAULT_RESPONSE = new byte[0];
public byte[] processMessage(byte[] message) {
log.info("Receive message : {}", message);
...
return DEFAULT_RESPONSE;
}
}
실제 메세지를 받고나서 비지니스로직이 돌아가는 Service단
TcpApplication.java
@SpringBootApplication
public class TcpApplication {
public static void main(String[] args) {
SpringApplication.run(TcpApplication.class, args);
}
}
spring boot application 돌아가기 위해선 꼭 필요한 @SpringBootApplication
Application을 시작해보면 잘 올라오는 것을 확인 할 수 있다
테스트는 Client를 만들어 확인해보기로 한다
'개발 > JAVA' 카테고리의 다른 글
[ Java ] 자바 정규식 (Regular expressions) (0) | 2021.01.19 |
---|---|
[ TCP ] TCP Client 만들기 (3) | 2021.01.06 |
[ java ] sdkman으로 자바 버전 관리하기 (0) | 2020.10.17 |
[ Java ] java8 list 비교 (0) | 2020.06.04 |
Java 자릿수 맞추기 ( 숫자 0 넣기 ) (0) | 2020.05.26 |