Notice
Recent Posts
Recent Comments
250x250
Creative Code
Chapter1(서버,클라이언트 통신) 본문
728x90
※hello_server.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
void error_handling(char *message);
int main(int argc, char *argv[])
{
int serv_sock; // 서버 소켓 디스크립터
int clnt_sock; // 클라이언트 소켓 디스크립터
struct sockaddr_in serv_addr; // 서버 주소 구조체
struct sockaddr_in clnt_addr; // 클라이언트 주소 구조체
socklen_t clnt_addr_size; // 클라이언트 주소 구조체의 크기
char message[10]; // 메시지를 저장할 버퍼
if (argc != 2) {
printf("Usage : %s <port>\n", argv[0]); // 프로그램 사용법 출력
exit(1); // 프로그램 종료
}
// 서버 소켓 생성
serv_sock = socket(PF_INET, SOCK_STREAM, 0);
if (serv_sock == -1)
error_handling("socket() error");
// 서버 주소 구조체 초기화
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET; // IPv4 형식 설정
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); // 모든 네트워크 인터페이스에서 접속 허용
serv_addr.sin_port = htons(atoi(argv[1])); // 사용자가 입력한 포트 번호 설정
// 소켓에 주소 정보 할당
if (bind(serv_sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) == -1)
error_handling("bind() error");
// 연결 대기 상태로 변경
if (listen(serv_sock, 5) == -1)
error_handling("listen() error");
clnt_addr_size = sizeof(clnt_addr);
// 클라이언트의 연결 요청을 수락
clnt_sock = accept(serv_sock, (struct sockaddr*)&clnt_addr, &clnt_addr_size);
if (clnt_sock == -1)
error_handling("accept() error");
// 표준 입력에서 메시지를 읽어서 클라이언트에게 전송
read(0, message, 10);
write(clnt_sock, message, sizeof(message));
char *str_ptr;
printf("clnt addr:%#x \n", clnt_addr.sin_addr); // 클라이언트 주소 출력
printf("clnt port:%#x \n", clnt_addr.sin_port); // 클라이언트 포트 출력
str_ptr = inet_ntoa(clnt_addr.sin_addr); // 클라이언트 주소를 문자열로 변환
printf("Dotted_Decimal notation1: %s\n", str_ptr);
close(clnt_sock);
close(serv_sock);
return 0;
}
void error_handling(char *message)
{
fputs(message, stderr); // 오류 메시지를 표준 오류 스트림에 출력
fputc('\n', stderr); // 개행 문자 출력
exit(1); // 프로그램 종료
}
※hello_client.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
void error_handling(char *message);
int main(int argc, char* argv[])
{
int sock; // 소켓 디스크립터를 저장할 변수
struct sockaddr_in serv_addr; // 서버의 주소 정보를 저장할 구조체
char message[30]; // 서버로부터 받을 메시지를 저장할 버퍼
int str_len; // 읽은 메시지의 길이를 저장할 변수
if(argc!=3){
printf("Usage : %s <IP> <port>\n", argv[0]); // 프로그램 사용법 출력
exit(1); // 프로그램 종료
}
sock = socket(PF_INET, SOCK_STREAM, 0); // 소켓 생성
if(sock == -1)
error_handling("socket() error"); // 소켓 생성 실패 시 오류 처리 함수 호출
memset(&serv_addr, 0, sizeof(serv_addr)); // serv_addr 구조체 초기화
serv_addr.sin_family = AF_INET; // 주소 체계 설정 (IPv4)
serv_addr.sin_addr.s_addr = inet_addr(argv[1]); // 서버 IP 주소 설정
serv_addr.sin_port = htons(atoi(argv[2])); // 서버 포트 번호 설정
if(connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) == -1)
error_handling("connect() error!"); // 서버에 연결 실패 시 오류 처리 함수 호출
str_len = read(sock, message, sizeof(message) - 1); // 서버로부터 데이터 읽기
if(str_len == -1)
error_handling("read() error!"); // 데이터 읽기 실패 시 오류 처리 함수 호출
message[str_len] = '\0'; // 문자열 마지막에 널 문자 추가하여 문자열 종료
printf("Message from server: %s \n", message); // 서버로부터 받은 메시지 출력
close(sock); // 소켓 닫기
return 0;
}
void error_handling(char *message)
{
fputs(message, stderr); // 오류 메시지를 표준 오류 스트림에 출력
fputc('\n', stderr); // 개행 문자 출력
exit(1); // 프로그램 종료
}
이후 cmd창에서 ./hello_server 9190으로 포트번호까지 설정해 서버를 열어준뒤
또다른 cmd창에서 ./hello_client + IP주소 + 9190으로 서버에 접속할 수 있다.
※low_open.c파일
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
void error_handling(char* message);
int main(void)
{
int fd1,fd2;
char buf[]="Let's go!\n";
fd1=open("data.txt", O_CREAT /*필요시 파일 생성*/ |O_WRONLY/*쓰기용도*/ |O_TRUNC /*모든 내용 삭제*/); // fopen -> 파일을 열기위한 함수, open -> 파일,장치등을 열기위한 함수
if(fd1==-1) // 파일을 열지 못했을 때
error_handling("open() error!");
printf("file descriptor: %d \n", fd1); // 파일 디스크립트 값 출력
fd2=open("data2.txt", O_CREAT /*필요시 파일 생성*/ |O_WRONLY/*쓰기용도*/ |O_TRUNC /*모든 내용 삭제*/); // fopen -> 파일을 열기위한 함수, open -> 파일,장치등을 열기위한 함수
if(fd2==-1) // 파일을 열지 못했을 때
error_handling("open() error!");
printf("file descriptor: %d \n", fd2); // 파일 디스크립트 값 출력
if(write(fd1, buf, sizeof(buf))==-1) //파일에 쓰기 실패했을 때
error_handling("write() error!");
close(fd1);
if(write(fd2, buf, sizeof(buf))==-1) //파일에 쓰기 실패했을 때
error_handling("write() error!");
close(fd2);
return 0;
}
void error_handling(char* message)
{
fputs(message, stderr);
fputc('\n', stderr);
exit(1);
}
/*
root@com:/home/swyoon/tcpip# gcc low_open.c -o lopen
root@com:/home/swyoon/tcpip# ./lopen
file descriptor: 3
root@com:/home/swyoon/tcpip# cat data.txt
Let's go!
root@com:/home/swyoon/tcpip#
*/
sudo chmod 777 data*로 파일의 권한을 모두 바꿔줘야한다.
※low_read.c파일
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#define BUF_SIZE 100
void error_handling(char* message);
int main(void)
{
int fd; // 파일 디스크립터를 저장할 변수
char buf[BUF_SIZE]; // 데이터를 읽고 쓸 버퍼
fd = open("data.txt", O_RDWR); // "data.txt" 파일을 열고 파일 디스크립터를 반환
if (fd == -1)
error_handling("open() error!"); // 파일 열기 실패 시 오류 처리 함수 호출
printf("file descriptor: %d\n", fd); // 파일 디스크립터 출력
// 표준 입력(0)에서 데이터를 읽어서 buf에 저장
if (read(0, buf, sizeof(buf)) == -1)
error_handling("read() error!"); // 읽기 실패 시 오류 처리 함수 호출
// 파일 디스크립터(fd)를 통해 buf의 내용을 파일에 씀
if (write(fd, buf, sizeof(buf)) == -1) {
error_handling("write() error!"); // 쓰기 실패 시 오류 처리 함수 호출
}
printf("file data: %s", buf); // 버퍼에 저장된 데이터 출력
close(fd); // 파일 디스크립터를 닫음
return 0;
}
void error_handling(char* message)
{
fputs(message, stderr); // 오류 메시지를 표준 오류 스트림에 출력
fputc('\n', stderr); // 개행 문자 출력
exit(1); // 프로그램 종료
}
※fd_seri.c파일
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/socket.h>
int main(void)
{
int fd1, fd2, fd3;
fd1=socket(PF_INET, SOCK_STREAM, 0); // 소켓 생성
fd2=open("test.dat", O_CREAT|O_WRONLY|O_TRUNC); //파일 생성
fd3=socket(PF_INET, SOCK_DGRAM, 0); // 소켓 생성
printf("file descriptor 1: %d\n", fd1);
printf("file descriptor 2: %d\n", fd2);
printf("file descriptor 3: %d\n", fd3);
close(fd1);
close(fd2);
close(fd3);
return 0;
}
728x90
'TCP IP 소켓프로그래밍' 카테고리의 다른 글
Chapter8(호스트 정보 조회) (1) | 2023.10.11 |
---|---|
Chapter9(버퍼 입력받기) (0) | 2023.10.11 |
Chapter5(echo_client) (0) | 2023.10.11 |
Chapter4(서버에 순차접속) (0) | 2023.10.11 |
Chapter3(서버에 접속한 IP주소, 포트번호 출력) (0) | 2023.10.10 |