5 단계. day3 네트워크 프로그래밍 프로그래밍 데모 TPC 기반 네트워크 프로토콜, FTP 기능 클래스

1. 클라이언트

// cilent 코드

#INCLUDE <STDIO.H>
#INCLUDE <SYS / types.h>
#INCLUDE <SYS / socket.h>
#INCLUDE <리눅스 / in.h>
사용법 #include <string.h>
#INCLUDE <SYS / stat.h>
사용법 #include <fcntl.h>

#DEFINE 크기 128

보이드 client_list (INT의 socket_fd);

보이드 client_get (INT의 socket_fd, 숯의 bufsend *);
보이드 client_put (INT의 socket_fd, 숯의 bufsend *);

메인 INT (int argc, 문자 CONST는 * argv와는 [])
{
(. ARGC는 <3) {IF
의 printf ( "USRMSG 이름은 % S <IP 허용> <포트> \ N-」라고는 argv [0]);
-1 반환;
}
/ / 링크 및 통신 소켓 생성
INT의 socket_fd 단계;
socket_fd = 소켓 (AF_INET, SOCK_STREAM, 0),
IF (socket_fd == -1) {
perror는 ( "소켓")
-1 반환;
}
의 printf ( "소켓 \ OK N-을 ");

// 구조 sockadd_in 파라미터 통과 기입
INT의 connect_fd 단계;
상기를 sockaddr_in ServerAddr를 구조체
(ServerAddr, sizeof의 (ServerAddr))를 bzero;
serveraddr.sin_family = AF_INET;
serveraddr.sin_port = htons (된 atoi (argv와 [2]));
serveraddr.sin_addr = inet_addr은의 .s_addr (argv와의 [. 1])
// 연결 링크
connect_fd = 연결 (socket_fd (SOCKADDR의 *를 구조체) ServerAddr, sizeof의 (ServerAddr));
IF (connect_fd == -1) {
perror는 ( "연결");
-1을 리턴;
}
의 printf ( "연결 OK \ N- ')를;
//는 버퍼 (BUF)에 받아 보내는
숯 bufsend [크기]
숯 bufrecv [SIZE] = {0}

// 송신 및 사이클을 성공적으로 검증 된 송신, 수신
하면서 (1 ) {
의 printf ( "*************** 목록 ************** \ N-");
의 printf ( ") "N ********** \ 파일 이름을 넣어 ***********;
의 printf는 ( "N ********** \ 파일 이름을 얻을 ***********");
의 printf ( "*************** 종료 ************** \ n을");
의 printf ( ">> MSG를 선택");

는 fgets (bufsend, SIZE, 표준 입력);
bufsend [나 strlen (bufsend) -1] =의 '\ 0';

스위치 (bufsend [0]) {
경우, 'L'
client_list (socket_fd);
단절;
경우 'P'
의 printf ( "넣어 \ n을을 보내");
client_put (socket_fd, bufsend + 4);
단절;
경우 'g'
의 printf ( "GET \ 없음을 보내");
client_get (socket_fd, bufsend + 4);
단절;
경우 'Q'
의 printf ( "\ n을 종료");
확대 (socket_fd);
0을 반환;
기본값 :
printf와 ( "오류 \ n을 선택");
단절;
}

}
닫기 (socket_fd)를;
0을 반환;
}

보이드 client_list (INT socket_fd)
{
INT의 recvbyte, I = 1;
숯 BUF [SIZE] = {0};
sprintf와 (BUF, "L");
보낼 (socket_fd, BUF,는 sizeof (BUF), 0); //发送L의给服务器

동안 (1) {
memset 함수 (BUF, 0, SIZE);
recvbyte = RECV (socket_fd, BUF,는 sizeof (BUF), 0);

(strncmp (BUF '! QQQ "4) == 0)의 경우
체류;

의 printf ( "%의 D %의 \ n."내가 ++ BUF);
}
의 printf ( "클라이언트 목록을 확인 \ n을입니다");
}

 

보이드 client_get (INT의 socket_fd, 숯의 bufsend *)
{
숯 BUF [SIZE];
sprintf와 (BUF 'G % s의 "bufsend);
보낼 (socket_fd (무효 *) BUF,는 sizeof (BUF)를, 0);
FDD INT, N;
경우 (FDD (= 개방 (BUF + 2 O_WRONLY | O_CREAT | O_TRUNC, 0666)) == -1) {
perror는 ( "opendes을");
반환;
}

INT의 recvbyte;
(1) {동안
memset 함수 (BUF, 0, SIZE);
recvbyte = RECV (socket_fd, BUF,는 sizeof (BUF), 0);

(strncmp (BUF '! QQQ "4) == 0)의 경우
체류;

(FDD, BUF, recvbyte) 물품;

}
의 printf ( "클라이언트 확인 \ n을 얻을");
확대 (FDD);

}

보이드 client_put (INT의 socket_fd, 숯의 bufsend *)
{
숯 BUF [SIZE];
sprintf와 (BUF, "P % s의"bufsend);
보낼 (socket_fd (무효 *) BUF,는 sizeof (BUF)를, 0);

FDS를 INT, N;
경우 ((FDS의 오픈 = (bufsend, O_RDONLY)) == -1) {
perror는 ( "opensrc");
반환;
}

반면 ((N = 판독 (FDS, BUF, 64))> 0) {
보내 (socket_fd, BUF, N, 0);
usleep (10000);
}
strcpy를 (BUF "QQQ!");
보낼 (socket_fd, BUF,는 sizeof (BUF), 0);
의 printf ( "클라이언트 확인 \ n을 넣어");
확대 (FDS);

}

2. 서버 코드


// 서버 코드

#INCLUDE <STDIO.H>
#INCLUDE <SYS / types.h>
#INCLUDE <SYS / socket.h>
#INCLUDE <리눅스 / in.h>
사용법 #include <string.h>
#INCLUDE <dirent.h를>
#INCLUDE <SYS / stat.h>
사용법 #include <fcntl.h>

#DEFINE 크기 128

보이드 server_get (INT의 accept_fd, 숯의 bufrecv *);
보이드 server_put (INT의 accept_fd, 숯의 bufrecv *);
보이드 server_list (INT의 accept_fd);

메인 INT (int argc, 문자 CONST는 * argv와는 [])
{
(ARGC는 <2) {IF
의 printf ( "USRMSG 이름은 : S % <포트> \ N-」라고는 argv [0]);
-1 반환;
}
// 1.. 링크에 사용되는 소켓 파일 작성
; INT socket_fd
; socket_fd = 소켓 (AF_INET, SOCK_STREAM, 0)
{IF (socket_fd == -1)
perror는 ( "소켓")
-1을 리턴;
}
의 printf ( "OK 소켓 생성을 \ n ");

// 매개 변수 전달을위한 구조를 sockaddr_in 채우기
INT의 bind_fd 단계;
// 패킹 구조를 정의하며를 sockaddr_in ServerAddr 구조체
bzero ((무효 *) ServerAddr, sizeof의 (ServerAddr)을)
serveraddr.sin_family = AF_INET; // IPv4 프로토콜의
ServerAddr .sin_port = htons (된 atoi (argv를 [ 1])) // 로컬 네트워크 포트 번호 변환 비트 바이트
serveraddr.sin_addr.s_addr = htonl (INADDR_ANY); // 로컬 IP 네트워크 바이트 비트 변환 코드, 임의의 IP
/ . / 2 결합 소켓 디스크립터, 포트는 IP의
bind_fd = 바인드 (socket_fd (SOCKADDR의 *를 구조체) ServerAddr, sizeof의 (ServerAddr));
IF (bind_fd == -1) {
perror는 ( "바인딩");
리턴 - . 1;
}
의 printf ( "바인드 OK의 \의 N-");

// 3 모니터, 패시브 모드의 활성 소켓 파일 속성
의 INT listen_fd;
listen_fd는 = 제 (socket_fd 10) 청취;

경우 (listen_fd == -1) {
perror는 ( "수신");
-1을 리턴;
}
의 printf ( "확인 \ n을 듣고");

INT는 accept_fd;
하지만 (1) {

// 4 차단 기능은 링크에 대한 클라이언트 요청을 기다리고, 링크는 NULL 기입 클라이언트하지 우려
= accept_fd 수락 (socket_fd, NULL NULL);
IF (accept_fd == -1) {
perror는 ( "승인");
반환 -1;
}
에서 printf ( "OK \ N-에 동의합니다");

//循环接收信息
CHAR bufrecv [SIZE] = {0};
INT의 recvbyte;
(1) {동안
memset 함수 (bufrecv, 0, SIZE);
의 printf ( "RECV 대기 : \ n을");
recvbyte = RECV (accept_fd (무효 *) bufrecv, SIZE, 0);

경우 (recvbyte> 0) {
스위치 (bufrecv [0]) {
경우, 'L'
server_list (accept_fd);
단절;
경우 'P'
의 printf ( "RECV 넣어 \ 없음");
server_put (accept_fd, bufrecv + 2);
단절;
케이스 'G'
의 printf ( "RECV get 및 \ 없음");
server_get (accept_fd, bufrecv + 2);
단절;
}
}

(recvbyte <0) {다른 경우
의 printf ( "RECV는 다음 연결을 기다리고 \ n 실패합니다.");
단절;
}
다른 {
의 printf ( "다음 연결을 기다리고, 휴식을 연결합니다. \ n");
확대 (accept_fd);
단절;
}

}
}
닫기 (accept_fd)를;
확대 (socket_fd);

0을 반환;
}


보이드 server_list (INT accept_fd)
{
DIR *와 dirp;
구조체에 dirent * 덴트;
구조체 합계 온도;

와 dirp =했던 opendir ( ".");
숯 BUF [SIZE] = {0};
반면 ((오목 = readdir은 (와 dirp)) = NULL!)
{
경우 (strncmp (dent-> d_name, 1) == 0 ".")
계속;

STAT (dent-> d_name, 온도);
경우 (S_ISDIR (temp.st_mode)! = 0)
계속;
memset 함수 (BUF, 0, SIZE);
의 strcpy (BUF, dent-> d_name);
(accept_fd, BUF,는 sizeof (BUF), 0)를 전송;
usleep (10000); //防止栈包
}

memset 함수 (BUF, 0, SIZE);
strcpy를 (BUF "QQQ!");
(accept_fd, BUF,는 sizeof (BUF), 0)를 전송;
의 printf ( "서버 목록이 확인 \ n을입니다");
closedir (와 dirp);
반환;

}

보이드 server_get (INT의 accept_fd, * CHAR는 bufrecv)
{
FDS를 INT, N;
숯 BUF [SIZE];
경우 ((FDS의 오픈 = (bufrecv, O_RDONLY)) == -1) {
perror는 ( "opensrc");
반환;
}

반면 ((N = 판독 (FDS, BUF, SIZE))> 0) {
보내 (accept_fd, BUF, N, 0);
usleep (10000);
}
strcpy를 (BUF "QQQ!");
(accept_fd, BUF,는 sizeof (BUF), 0)를 전송;
의 printf ( "서버 확인 \ n을 얻을");
확대 (FDS);
}


보이드 server_put (INT의 accept_fd, 숯의 bufrecv *)
{
INT의 FDD, N;
경우 ((FDD (= 개방 bufrecv, O_WRONLY | O_CREAT | O_TRUNC, 0666)) == -1) {
perror는 ( "opendes을");
반환;
}

숯 BUF [SIZE] = {0};
INT의 recvbyte;
(1) {동안
memset 함수 (BUF, 0, SIZE);
recvbyte = RECV (accept_fd (무효 *) BUF,는 sizeof (BUF), 0);
(strncmp (BUF '! QQQ "4) == 0)의 경우
체류;

(FDD, BUF, recvbyte) 물품;
}
의 printf ( "서버 확인 \ n을 넣어");
확대 (FDD);

}

 

추천

출처www.cnblogs.com/huiji12321/p/11371398.html