반응형
Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- 엑스퍼트생일축하해
- TCP/IP
- QT TCP
- #부동산전자거래 #부동산전자계약 #부동산계약 #부동산전자계약방법 #부동산전자계약하는법 #부동산계약방법 #부동산중개수수료 #부동산중개수수료아끼기 #부동산복비아끼기
- 엑스퍼트2주년
- object
- lua for windows
- 월세
- C++ API
- file read
- 청량리역한양수자인192
- 프리미어 영상저장
- lua interpreter
- 중소규모택지
- 프리미어 영상변환
- Lua
- 등록임대주택
- QTcpServer
- FILE TRANSFER
- meta table
- 찾다죽는줄
- file write
- lua setup
- lua install
- 수도권주택공급
- file open
- 티몬삼겹살데이
- #신혼부부 #결혼준비 #신혼부부희망타운신혼부부특별공급
- 국토교통부
- C API
Archives
- Today
- Total
Value Creator의 IT(프로그래밍 / 전자제품)
Chapter 15 소켓과 표준 입출력 본문
반응형
-----------------------------------------------------------------------------------------------------------------------------------
표준 입출력 함수는 버퍼링을 사용하기 때문에 전송속도가 빠르다.
같은 경로에 임의의 파일을 하나 만들어놓고, 복사속도를 비교해보면 알 수 있다.
용량이 클수록 속도 차이를 확연히 느낄 수 있다.
시스템 함수(open, close, read, write)
syscpy.c
#include <stdio.h>
#include <fcntl.h>
#define BUF_SIZE 3
int main(int argc, char *argv[])
{
int fd1, fd2, len;
char buf[BUF_SIZE];
fd1=open("test300mb.zip", O_RDONLY);
fd2=open("cpy_test300mb.zip", O_WRONLY|O_CREAT|O_TRUNC);
while((len=read(fd1, buf, sizeof(buf)))>0)
write(fd2, buf, len);
close(fd1);
close(fd2);
return 0;
}
표준 입출력 함수(fopen, fclose, fgets, fputs)
stdcpy.c
#include <stdio.h>
#define BUF_SIZE 3
int main(int argc, char *argv[])
{
FILE * fp1; //표준 입출력함수는 FILE 구조체 포인터를 사용한다.
FILE * fp2;
char buf[BUF_SIZE];
fp1=fopen("test300mb.zip", "r");
fp2=fopen("cpyStdcpy_test300mb.zip", "w");
while(fgets(buf, BUF_SIZE, fp1)!=NULL)
fputs(buf, fp2);
fclose(fp1);
fclose(fp2);
return 0;
}
소켓을 생성할 때 반환되는 것은 파일 디스크립터이다. 파일 디스크립터를 FILE 구조체 포인터로 변환해야 표준 입출력 함수에서 소켓을 사용할 수 있다.
fdopen 함수를 이용. 파일 디스크립터를 FILE 구조체 포인터로 변환.
(file descriptor -> FILE 구조체 포인터)
desto.c
#include <stdio.h>
#include <fcntl.h>
int main(void)
{
FILE *fp;
int fd=open("data.dat", O_WRONLY|O_CREAT|O_TRUNC); //파일 디스크립터 선언
if(fd==-1)
{
fputs("file open error", stdout);
return -1;
}
fp=fdopen(fd, "w"); //write 모드의 FILE 구조체 포인터 반환
fputs("Network C programming \n", fp);
fclose(fp);
return 0;
}
fileno 함수를 이용. FILE 구조체 포인터를 파일 디스크립터로 변환.
(FILE 구조체 포인터 -> 파일 디스크립터)
todes.c
#include <stdio.h>
#include <fcntl.h>
int main(void)
{
FILE *fp;
int fd=open("data.dat", O_WRONLY|O_CREAT|O_TRUNC); //파일 디스크립터 선언
if(fd==-1)
{
fputs("file open error", stdout);
return -1;
}
printf("First file descriptor: %d \n", fd); //파일 디스크립터 번호 출력
fp=fdopen(fd, "w"); //파일 디스크립터를 FILE 구조체 포인터로 변환
fputs("TCP/IP SOCKET PROGRAMMING \n", fp);
printf("Second file descriptor: %d \n", fileno(fp)); //FILE 구조체 포인터를 파일 디스크립터로 변환
fclose(fp);
return 0;
}
아래 코드는 Chapter4의 에코 서버와 에코 클라이언트 소스코드를 약간 변경한 것이다.
fdopen함수와 표준 입출력 함수를 사용한다는 것만 변했다.
2019/10/29 - [1. 프로그래밍/4) Network] - Chapter 4 TCP 기반 서버 클라이언트
소켓 기반 표준 C 입출력 함수 호출
echo_stdserv.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#define BUF_SIZE 1024
void error_handling(char *message);
int main(int argc, char *argv[])
{
int serv_sock, clnt_sock;
char message[BUF_SIZE];
int str_len, i;
struct sockaddr_in serv_adr;
struct sockaddr_in clnt_adr;
socklen_t clnt_adr_sz;
FILE * readfp; //입력을 받을 소켓을 FILE 구조체 포인터로 선언
FILE * writefp; //출력을 받을 소켓을 FILE 구조체 포인터로 선언
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_adr, 0, sizeof(serv_adr));
serv_adr.sin_family=AF_INET;
serv_adr.sin_addr.s_addr=htonl(INADDR_ANY);
serv_adr.sin_port=htons(atoi(argv[1]));
if(bind(serv_sock, (struct sockaddr*)&serv_adr, sizeof(serv_adr))==-1)
error_handling("bind() error");
if(listen(serv_sock, 5)==-1)
error_handling("listen() error");
clnt_adr_sz=sizeof(clnt_adr);
for(i=0; i<5; i++)
{
clnt_sock=accept(serv_sock, (struct sockaddr*)&clnt_adr, &clnt_adr_sz);
if(clnt_sock==-1)
error_handling("accept() error");
else
printf("Connected client %d \n", i+1);
readfp=fdopen(clnt_sock, "r"); //fdopen으로 클라이언트 소켓 파일디스크립터의 입력부분을 FILE 구조체 포인터로 변환
writefp=fdopen(clnt_sock, "w"); //클라이언트 소켓 파일디스크립터의 출력부분을 FILE 구조체 포인터로 변환
while(!feof(readfp)) //EOF가 들어올때까지 읽기 실행
{
fgets(message, BUF_SIZE, readfp);
fputs(message, writefp);
fflush(writefp); //fflush를 통해서 데이터 전송?
}
fclose(readfp);
fclose(writefp);
}
close(serv_sock);
return 0;
}
void error_handling(char *message)
{
fputs(message, stderr);
fputc('\n', stderr);
exit(1);
}
echo_stdclnt.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#define BUF_SIZE 1024
void error_handling(char *message);
int main(int argc, char *argv[])
{
int sock;
char message[BUF_SIZE];
int str_len;
struct sockaddr_in serv_adr;
FILE * readfp;
FILE * writefp;
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_adr, 0, sizeof(serv_adr));
serv_adr.sin_family=AF_INET;
serv_adr.sin_addr.s_addr=inet_addr(argv[1]);
serv_adr.sin_port=htons(atoi(argv[2]));
if(connect(sock, (struct sockaddr*)&serv_adr, sizeof(serv_adr))==-1)
error_handling("connect() error!");
else
puts("Connected...........");
readfp=fdopen(sock, "r");
writefp=fdopen(sock, "w"); //각종 선언은 서버 부분과 유사
while(1)
{
fputs("Input message(Q to quit): ", stdout);
fgets(message, BUF_SIZE, stdin); //메세지를 입력 받기 scanf와 유사
if(!strcmp(message,"q\n") || !strcmp(message,"Q\n"))
break; //입력받은 값이 q나 Q라면 while문 중단
fputs(message, writefp); //message를 writefp라는 출력 버퍼로 옮김
fflush(writefp); //??
fgets(message, BUF_SIZE, readfp); //message를 readfp로 읽기??
printf("Message from server: %s", message);
}
fclose(writefp);
fclose(readfp);
return 0;
}
void error_handling(char *message)
{
fputs(message, stderr);
fputc('\n', stderr);
exit(1);
}
반응형
'1. 프로그래밍 > 4) Network' 카테고리의 다른 글
Chapter 17 epoll 기반 IO 멀티플렉싱 서버 구현 (0) | 2019.11.07 |
---|---|
Chapter 16 입출력 스트림 분리 (0) | 2019.11.07 |
Chapter 14 추후 작성 (0) | 2019.11.07 |
Chapter 13 입출력 함수(send, recv, read, write) (0) | 2019.11.06 |
Chapter 12 IO 멀티플렉싱 (0) | 2019.11.06 |
Comments