TCP Server Socket Programming
다음은 윈도우즈 OS에서 TCP 기반 소켓 프로그래밍-서버측 코드입니다.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")
#define MAX_BUFFER_SIZE 1024
int main() {
WSADATA wsaData;
SOCKET serverSocket, clientSocket;
struct sockaddr_in serverAddr, clientAddr;
char buffer[MAX_BUFFER_SIZE];
int clientAddrSize;
// Winsock 초기화
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
printf("Failed to initialize winsock.\n");
return -1;
}
// 소켓 생성
if ((serverSocket = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) {
printf("Failed to create socket.\n");
return -1;
}
// 서버 설정
serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);
serverAddr.sin_port = htons(5001);
// 소켓 바인딩
if (bind(serverSocket, (struct sockaddr*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR) {
printf("Failed to bind socket.\n");
return -1;
}
// 클라이언트의 연결 대기
if (listen(serverSocket, 1) == SOCKET_ERROR) {
printf("Failed to listen on socket.\n");
return -1;
}
printf("서버가 실행 중입니다...\n");
// 클라이언트 연결 수락
clientAddrSize = sizeof(clientAddr);
if ((clientSocket = accept(serverSocket, (struct sockaddr*)&clientAddr, &clientAddrSize)) == INVALID_SOCKET) {
printf("Failed to accept client connection.\n");
return -1;
}
printf("클라이언트가 연결되었습니다.\n");
while (1) {
// 클라이언트로부터 메시지 수신
memset(buffer, 0, MAX_BUFFER_SIZE);
int bytesRead = recv(clientSocket, buffer, MAX_BUFFER_SIZE, 0);
if (bytesRead == SOCKET_ERROR || bytesRead == 0) {
break;
}
printf("수신한 메시지: %s\n", buffer);
// 클라이언트에게 응답 전송
char response[MAX_BUFFER_SIZE];
snprintf(response, MAX_BUFFER_SIZE, "서버가 메시지를 수신했습니다: %s", buffer);
send(clientSocket, response, strlen(response), 0);
}
// 연결 종료
closesocket(clientSocket);
closesocket(serverSocket);
WSACleanup();
return 0;
}
TCP Client Socket Programming
다음은 윈도우즈 OS에서 TCP 기반 소켓 프로그래밍-클라이언트측 코드입니다.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#pragma comment(lib, "ws2_32.lib")
#define MAX_BUFFER_SIZE 1024
int main() {
WSADATA wsaData;
SOCKET clientSocket;
struct sockaddr_in serverAddr;
struct in_addr ipAddr;
char buffer[MAX_BUFFER_SIZE];
char message[MAX_BUFFER_SIZE];
// Winsock 초기화
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
printf("Failed to initialize winsock.\n");
return -1;
}
// 소켓 생성
if ((clientSocket = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) {
printf("Failed to create socket.\n");
return -1;
}
// 서버 정보 설정
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(5001);
if (inet_pton(AF_INET, "127.0.0.1", &serverAddr.sin_addr) <= 0) {
printf("Invalid address/ Address not supported.\n");
return -1;
}
// 서버에 연결
if (connect(clientSocket, (struct sockaddr*)&serverAddr, sizeof(serverAddr)) < 0) {
printf("Failed to connect to server.\n");
return -1;
}
while (1) {
// 사용자로부터 메시지 입력
printf("메시지를 입력하세요 (종료하려면 q 또는 Q): ");
fgets(message, MAX_BUFFER_SIZE, stdin);
message[strcspn(message, "\n")] = '\0';
if (strcmp(message, "q") == 0 || strcmp(message, "Q") == 0) {
break;
}
// 서버로 메시지 전송
send(clientSocket, message, strlen(message), 0);
// 서버로부터 응답 수신
memset(buffer, 0, MAX_BUFFER_SIZE);
int bytesRead = recv(clientSocket, buffer, MAX_BUFFER_SIZE, 0);
if (bytesRead == SOCKET_ERROR || bytesRead == 0) {
break;
}
printf("서버로부터 받은 응답: %s\n", buffer);
}
// 연결 종료
closesocket(clientSocket);
WSACleanup();
return 0;
}
메세지를 보내보면 :
연결된 것을 확인할 수 있습니다.
와이어샤크를 통해서도 확인해볼 수 있습니다.
q를 입력해서 정상적으로 종료하는게 아닌 창닫기를 통해 강제로 종료시
RST 리셋이 나오는걸 확인해보았습니다.
STS4를 활용한 자바버전으로도 확인해보았습니다.
TCP Server Socket Programming
다음은 자바를 활용한 TCP 기반 소켓 프로그래밍-서버측 코드입니다.
package com.taehun.server;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class TCPServer {
private static final int PORT = 5001;
private static final int MAX_BUFFER_SIZE = 1024;
public static void main(String[] args) {
ServerSocket serverSocket = null;
Socket clientSocket = null;
try {
// 서버 소켓 생성
serverSocket = new ServerSocket(PORT);
System.out.println("서버가 실행 중입니다...");
// 클라이언트 연결 수락
clientSocket = serverSocket.accept();
System.out.println("클라이언트가 연결되었습니다.");
// 클라이언트로부터 메시지 수신을 위한 InputStream 생성
InputStream input = clientSocket.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(input));
// 클라이언트에게 메시지를 전송하기 위한 OutputStream 생성
OutputStream output = clientSocket.getOutputStream();
PrintWriter writer = new PrintWriter(output, true);
String clientMessage;
// 클라이언트로부터 메시지 수신 및 응답 전송 반복
while ((clientMessage = reader.readLine()) != null) {
System.out.println("수신한 메시지: " + clientMessage);
// 클라이언트에게 응답 전송
writer.println("서버가 메시지를 수신했습니다: " + clientMessage);
}
} catch (IOException e) {
System.out.println("서버 오류: " + e.getMessage());
e.printStackTrace();
} finally {
try {
if (clientSocket != null) {
clientSocket.close();
}
if (serverSocket != null) {
serverSocket.close();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
}
TCP Client Socket Programming
다음은 자바를 활용한 TCP 기반 소켓 프로그래밍-클라이언트측 코드입니다.
package com.taehun.client;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
public class TCPClient {
private static final String SERVER_ADDRESS = "192.168.0.85";
private static final int SERVER_PORT = 5001;
private static final int MAX_BUFFER_SIZE = 1024;
public static void main(String[] args) {
Socket socket = null;
BufferedReader reader = null;
PrintWriter writer = null;
try {
// 서버에 연결
socket = new Socket(SERVER_ADDRESS, SERVER_PORT);
System.out.println("서버에 연결되었습니다.");
// 서버로 데이터를 보내기 위한 PrintWriter
writer = new PrintWriter(socket.getOutputStream(), true);
// 서버로부터 데이터를 받기 위한 BufferedReader
reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
BufferedReader userInputReader = new BufferedReader(new InputStreamReader(System.in));
String userInput;
while (true) {
System.out.print("메시지를 입력하세요 (종료하려면 q 또는 Q): ");
userInput = userInputReader.readLine();
if ("q".equalsIgnoreCase(userInput)) {
break;
}
// 서버로 메시지 전송
writer.println(userInput);
// 서버로부터 응답 수신
String response = reader.readLine();
System.out.println("서버로부터 받은 응답: " + response);
}
} catch (IOException e) {
System.out.println("클라이언트 오류: " + e.getMessage());
e.printStackTrace();
} finally {
try {
if (reader != null) reader.close();
if (writer != null) writer.close();
if (socket != null) socket.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
}
콘솔창을 통해 연결된 것을 확인해 볼 수 있습니다.
'Network Study' 카테고리의 다른 글
HTTP 요청/응답 구조 (프로토콜, 메서드) (1) | 2024.09.27 |
---|---|
HTTP와 HTTPS (2) | 2024.09.27 |
TCP, UDP (0) | 2024.09.26 |
ICMP(Internet Control Message Protocol) (0) | 2024.09.26 |
DHCP (Dynamic Host Configuration Protocol) (1) | 2024.09.26 |