Professional Documents
Culture Documents
TCPIP Source
TCPIP Source
TCPIP Source
1 서버 프로그램
< 소스 hello_server.c>
#include <stdio.h>
#include <netinet/in.h>
#include <sys/socket.h>
main( )
int len;
int n;
memset(&s_addr, 0, sizeof(s_addr));
s_addr.sin_addr.s_addr = htonl(INADDR_ANY);
s_addr.sin_family = AF_INET;
s_addr.sin_port = htons(PORT);
1
return -1;
if(listen(s_socket, 5) == -1) {
printf("listen Fail\n");
return -1;
while(1) {
len = sizeof(c_addr);
n = strlen(buffer);
close(c_socket);
close(s_socket);
</ 소스 >
< 소스 hello_client.c>
#include <stdio.h>
#include <netinet/in.h>
#include <sys/socket.h>
2
#define PORT 9000
main( )
int c_socket;
int len;
int n;
char rcvBuffer[BUFSIZ];
memset(&c_addr, 0, sizeof(c_addr));
c_addr.sin_addr.s_addr = inet_addr(IPADDR);
c_addr.sin_family = AF_INET;
c_addr.sin_port = htons(PORT);
close(c_socket);
return -1;
3
return (-1);
rcvBuffer[n] = '\0';
close(c_socket);
</ 소스 >
< 소스 HelloClientDlg.h>
// HelloClientDlg.h : 헤더 파일
#pragma once
#include "afxwin.h"
// CHelloClientDlg 대화 상자
// 생성입니다 .
public:
// 대화 상자 데이터입니다 .
4
enum { IDD = IDD_HELLOCLIENT_DIALOG };
protected:
// 구현입니다 .
protected:
HICON m_hIcon;
// 생성된 메시지 맵 함수
DECLARE_MESSAGE_MAP( )
public:
public:
};
</ 소스 >
< 소스 HelloClientDlg.cpp>
// HelloClientDlg.cpp : 구현 파일
//
#include "stdafx.h"
5
#include "HelloClient.h"
#include "HelloClientDlg.h"
CSocket socket;
socket.Create( );
socket.Connect(_T("127.0.0.1"), 9000);
int cbRcvd;
char buffer[1024];
//strBuffer = (LPCSTR)(LPSTR)buffer;
strBuffer.Format("%s", buffer);
m_static_status.SetWindowText(strBuffer.Left(cbRcvd));
socket.Close( );
</ 소스 >
1.3.2 서버 프로그램
6
< 소스 ListenSocket.h>
#pragma once
// CListenSocket 명령 대상입니다 .
public:
virtual ~CListenSocket( );
public:
};
</ 소스 >
< 소스 ListenSocket.cpp>
// ListenSocket.cpp : 구현 파일입니다 .
//
#include "stdafx.h"
#include "HelloServer.h"
#include "ListenSocket.h"
7
// CListenSocket
CListenSocket::~CListenSocket( )
// CListenSocket 멤버 함수
m_pHelloServerDlg->ProcessAccept( ); --④
CSocket::OnAccept(nErrorCode);
</ 소스 >
< 소스 ServiceSocket.h>
#pragma once
// CServiceSocket 명령 대상입니다 .
8
class CHelloServerDlg; --①
public:
virtual ~CServiceSocket( );
};
</ 소스 >
< 소스 ServiceSocket.cpp>
// ServiceSocket.cpp : 구현 파일입니다 .
#include "stdafx.h"
#include "HelloServer.h"
#include "ServiceSocket.h"
// CServiceSocket
CServiceSocket::~CServiceSocket( )
9
{
</ 소스 >
< 소스 HelloServerDlg.h>
// HelloServerDlg.h : 헤더 파일
#pragma once
#include "afxwin.h"
// CHelloServerDlg 대화 상자
// 생성입니다 .
public:
// 대화 상자 데이터입니다 .
protected:
// 구현입니다 .
protected:
HICON m_hIcon;
10
// 생성된 메시지 맵 함수
DECLARE_MESSAGE_MAP( )
public:
public:
public:
public:
};
</ 소스 >
< 소스 HelloServerDlg.cpp>
// HelloServerDlg.cpp : 구현 파일
#include "stdafx.h"
#include "HelloServer.h"
#include "HelloServerDlg.h"
11
void CHelloServerDlg::OnBnClickedButtonStart( ) --①
if(!m_pListenSocket->Create(nPort)) {
return;
} else {
if(!m_pListenSocket->Listen( )) {
return;
if(m_pListenSocket->Accept(*m_pServiceSocket)) {
m_static_status.SetWindowText(_T("Accepted"));
12
m_pServiceSocket->Send(sndBuffer, (int)strlen(sndBuffer));
m_static_status.SetWindowText(_T("Send Hello,World"));
} else {
delete m_pServiceSocket;
</ 소스 >
13
2 장 내친김에 소켓 프로그래밍 확장하기
2.1.1 서버 프로그램
< 소스 hello_ext_server.c>
#include <stdio.h>
#include <netinet/in.h>
#include <sys/socket.h>
char rBuffer[BUFSIZ];
main( )
int len;
int n, i;
16
char *temp;
int length;
19
14
21
memset(&s_addr, 0, sizeof(s_addr));
s_addr.sin_addr.s_addr = htonl(INADDR_ANY);
s_addr.sin_family = AF_INET;
s_addr.sin_port = htons(PORT);
26
return -1;
31
if(listen(s_socket, 5) == -1) {
printf("listen Fail\n");
return -1;
36
while(1) {
len = sizeof(c_addr);
length = 0;
temp = rBuffer;
15
if(*temp == '\0') break;
temp++; length++;
rBuffer[length] = '\0';
if(!strcmp(rBuffer, "print") ) {
n = strlen(buffer);
close(c_socket);
close(s_socket);
</ 소스 >
< 소스 hello_ext_client.c>
#include <stdio.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <strings.h>
16
#define IPADDR "127.0.0.1"
char buffer[BUFSIZ];
main( )
int c_socket;
int len;
char rcvBuffer[BUFSIZ];
int n;
memset(&c_addr, 0, sizeof(c_addr));
c_addr.sin_addr.s_addr = inet_addr(IPADDR);
c_addr.sin_family = AF_INET;
c_addr.sin_port = htons(PORT);
27
close(c_socket);
return -1;
17
scanf("%s", buffer);
buffer[strlen(buffer)] = '\0';
return (-1);
rcvBuffer[n] = '\0';
44
close(c_socket);
</ 소스 >
2.2.1 파일 목록 읽어 내기
< 소스 list.c>
#include <dirent.h>
#include <stdio.h>
main( )
DIR *dp;
18
struct dirent *dir;
exit(-1);
if(dir->d_ino == 0) continue;
printf("%s\n", dir->d_name);
closedir(dp);
</ 소스 >
2.2.2 서버 프로그램
< 소스 ls_server.c>
//ls_server.c
#include <stdio.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <dirent.h>
19
char err_1[ ]="Directory Error";
char rBuffer[BUFSIZ];
main( )
int n, i;
char *temp;
DIR *dp;
memset(&s_addr, 0, sizeof(s_addr));
s_addr.sin_addr.s_addr = htonl(INADDR_ANY);
s_addr.sin_family = AF_INET;
s_addr.sin_port = htons(PORT);
return -1;
20
if(listen(s_socket, 5) == -1) {
printf("listen Fail\n");
return -1;
while(1) {
len = sizeof(c_addr);
length = 0;
temp = rBuffer;
temp++; length++;
rBuffer[length] = '\0';
if(!strcmp(rBuffer, "ls") ) {
21
write(c_socket, err_1, strlen(err_1));
} else {
if(dir->d_ino == 0) continue;
closedir(dp);
close(c_socket);
close(s_socket);
</ 소스 >
< 소스 ls_client.c>
//ls_client.c
#include <stdio.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <strings.h>
22
#define IPADDR "127.0.0.1"
char buffer[BUFSIZ];
main( )
int c_socket;
int len;
char rcvBuffer[BUFSIZ];
19
char *temp;
int length = 0;
int n;
24
memset(&c_addr, 0, sizeof(c_addr) );
c_addr.sin_addr.s_addr = inet_addr(IPADDR);
c_addr.sin_family = AF_INET;
c_addr.sin_port = htons(PORT);
23
close(c_socket);
return -1;
scanf("%s", buffer);
buffer[strlen(buffer)] = '\0';
printf("write error\n");
exit(-1);
temp = rcvBuffer;
temp++; length++;
rcvBuffer[length] = '\0';
52
close(c_socket);
</ 소스 >
24
3 장 소켓 프로그래밍에서 알아야 할 기본
< 소스 sock_open.c>
//sock_open.c
#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
main( )
perror("socket( )-tcpSd1");
} else
perror("socket( )-udpSd1");
} else
25
perror("socket( )-tcpSd2");
} else
perror("socket( )-udpSd2");
} else
close(tcpSd1);
close(udpSd1);
close(tcpSd2);
close(udpSd2);
</ 소스 >
< 소스 file_sock_open.c>
//file_sock_open.c
#include <stdio.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/socket.h>
main( )
int fd;
int sd;
26
fd = open("/etc/services", O_RDONLY);
</ 소스 >
< 소스 stdio.c>
//stdio.c
#include <stdio.h>
#include <sys/socket.h>
main( ) {
int sd;
char str[100];
</ 소스 >
< 소스 sockpair.c>
27
//sockpair.c
#include <stdio.h>
#include <sys/socket.h>
main( )
char buf[BUFSIZ];
buf[n2] = '\0';
close(sd[0]);
close(sd[1]);
</ 소스 >
28
< 소스 sockpair_fork.c>
//sockpair_fork.c
#include <stdio.h>
#include <sys/socket.h>
main( ) {
int pid;
char buf[BUFSIZ];
pid = fork( );
close(sd[1]);
close(sd[0]);
close(sd[0]);
29
write(sd[1], data2, sizeof(data2));
close(sd[1]);
perror("fork( )");
</ 소스 >
30
PART 2 단일 접속 서버 구현하기
4 장 클라이언트 / 서버 모델
< 소스 getservent.c>
//getservent.c
#include <stdio.h>
#include <netdb.h>
int
main( ) {
int n;
while(1) {
printf("\n");
31
</ 소스 >
< 소스 ordering.c>
//ordering.c
#include <stdio.h>
main( )
short data;
char *ch;
data = 0x1234;
ch = (char *) &data;
</ 소스 >
32
4.2.2 네트워크 / 호스트 바이트 순서 간 자료 변환
< 소스 ntoh_hton.c>
//ntoh_hton.c
#include <stdio.h>
main( ) {
short netData;
char *ch;
ch = (char *) &hostData;
printf("host(big-endian) : ");
printf("host(little-endian) : ");
netData = htons(hostData);
ch = (char *) &netData;
33
</ 소스 >
4.2.3 IP 주소 변환
< 소스 inet_aton.c>
//inet_aton.c
#include <stdio.h>
#include <arpa/inet.h>
main( ) {
char *addr;
inet_aton(ipAddr, &inp);
addr = inet_ntoa(inp);
</ 소스 >
< 소스 gethostbyname.c>
//gethostbyname.c
#include <netdb.h>
#include <sys/socket.h>
34
main( ) {
int i;
10
exit(-1);
17
i = 0;
while(host->h_aliases[i] != NULL ) {
22
25
i = 0;
while(host->h_addr_list[i] != NULL) {
35
>h_addr_list[i]));
i++;
</ 소스 >
< 소스 remote_addr.c>
//remote_addr.c
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
main( )
int tcpSd;
perror("socket( )");
exit(-1);
s_addr.sin_family = AF_INET;
36
inet_aton("203.249.39.3", &s_addr.sin_addr.s_addr);
s_addr.sin_port = htons(7);
close(tcpSd);
</ 소스 >
37
5장 TCP 소켓 프로그래밍
5.1 서버 프로그램의 기능 수행
5.1.1 연결 준비 단계
< 소스 bind_listen.c>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include <sys/socket.h>
main( )
int s_socket;
memset(&s_addr, 0, sizeof(s_addr));
s_addr.sin_family = AF_INET;
s_addr.sin_port = htons(0);
38
return -1;
listen(s_socket, 0);
while(1) {
sleep(2);
close(s_socket);
</ 소스 >
5.3.1 서버 프로그램
< 소스 echo_server.c>
//echo_server.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include <sys/socket.h>
main( )
39
{
int len;
int n;
char rcvBuffer[BUFSIZ];
memset(&s_addr, 0, sizeof(s_addr));
s_addr.sin_addr.s_addr = htonl(INADDR_ANY);
s_addr.sin_family = AF_INET;
s_addr.sin_port = htons(PORT);
return -1;
if(listen(s_socket, 5) == -1) {
printf("listen Fail\n");
return -1;
while(1) {
40
len = sizeof(c_addr);
rcvBuffer[n] = '\0';
printf("%s", rcvBuffer);
close(c_socket);
close(s_socket);
</ 소스 >
< 소스 echo_client.c>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include <sys/socket.h>
41
main( )
int c_socket;
int len;
int n;
memset(&c_addr, 0, sizeof(c_addr));
c_addr.sin_addr.s_addr = inet_addr(IPADDR);
c_addr.sin_family = AF_INET;
c_addr.sin_port = htons(PORT);
close(c_socket);
return -1;
while(1) {
42
sndBuffer[n] = '\0';
return (-1);
n_left = n;
n_recv = 0;
while(n_left > 0) {
return (-1);
n_left = n_left - n;
n_recv = n_recv + n;
rcvBuffer[n_recv] = '\0';
close(c_socket);
43
< 소스 >
44
6장 UDP 소켓 프로그래밍
6.3.1 서버 프로그램
< 소스 echo_server_UDP.c>
//echo_server_UDP.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
int sd;
char buff[BUFSIZ];
int n, n_recv;
int addr_len;
bzero(&s_addr, sizeof(s_addr));
s_addr.sin_family = AF_INET;
s_addr.sin_addr.s_addr = htonl(INADDR_ANY);
s_addr.sin_port = htons(9200);
45
if(bind(sd, (struct sockaddr *) &s_addr, sizeof(s_addr)) < 0){
exit(-2);
while(1) {
28
fprintf(stderr, "waiting\n");
30
addr_len = sizeof(c_addr);
&addr_len)) < 0) {
exit(-3);
0){
exit(-3);
close(sd);
</ 소스 >
46
6.3.2 클라이언트 프로그램
< 소스 echo_client_UDP.c>
//echo_client_UDP.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
int sd;
char sndBuffer[BUFSIZ];
int n, n_send;
int addr_len;
bzero(&s_addr, sizeof(s_addr));
s_addr.sin_family = AF_INET;
s_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
s_addr.sin_port = htons(9200);
while(1) {
47
fprintf(stderr, "waiting\n");
25
sndBuffer[n] = '\0';
exit(-3);
addr_len = sizeof(s_addr);
exit(-3);
sndBuffer[n] = '\0';
close(sd);
48
}
</ 소스 >
6.4.1 자료 전송 중의 손실
< 소스 echo_client_UDPalarm.c>
//echo_client_UDPalarm.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <signal.h>
#include <errno.h>
void sigAlarm(int);
int sd;
char sndBuffer[BUFSIZ];
int n, n_send;
int addr_len;
int status;
49
act.sa_handler = sigAlarm;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
bzero(&s_addr, sizeof(s_addr));
s_addr.sin_family = AF_INET;
s_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
s_addr.sin_port = htons(9200);
while(1) {
fprintf(stderr, "waiting\n");
sndBuffer[n] = '\0';
50
fprintf(stderr, "sendto( ) error");
exit(-3);
alarm(2);
addr_len = sizeof(s_addr);
if(errno == EINTR)
else
} else {
alarm(0);
sndBuffer[n] = '\0';
close(sd);
void
sigAlarm(int signo)
51
fprintf(stderr, "alarm\n");
return;
</ 소스 >
6.4.2 응답 대상에 대한 확인
< 소스 echo_client_UDPconfirm.c>
//echo_client_UDPconfirm.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
//#include <string.h>
int sd;
char sndBuffer[BUFSIZ];
int n, n_send;
int addr_len;
17
bzero(&s_addr, sizeof(s_addr));
s_addr.sin_family = AF_INET;
52
s_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
s_addr.sin_port = htons(9200);
while(1) {
fprintf(stderr, "waiting\n");
28
sndBuffer[n] = '\0';
exit(-3);
38
addr_len = sizeof(c_addr);
exit(-3);
53
44
inet_ntoa(c_addr.sin_addr.s_addr), ntohs(c_addr.sin_port));
continue;
sndBuffer[n] = '\0';
50
close(sd);
</ 소스 >
< 소스 echo_client_UDPconnect.c>
//echo_client_UDPconnect.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
int sd;
54
struct sockaddr_in s_addr;
char sndBuffer[BUFSIZ];
int n, n_send;
int addr_len;
bzero(&s_addr, sizeof(s_addr));
s_addr.sin_family = AF_INET;
s_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
s_addr.sin_port = htons(9000);
while(1) {
fprintf(stderr, "waiting\n");
27
sndBuffer[n] = '\0';
55
fprintf(stderr, "write error");
exit(-3);
addr_len = sizeof(s_addr);
exit(-3);
sndBuffer[n] = '\0';
close(sd);
</ 소스 >
< 소스 UDPbcaster.c>
//UDPbcaster.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
56
#include <netinet/in.h>
#include <signal.h>
#include <errno.h>
int sd;
char sndBuffer[BUFSIZ];
int on = 1;
if(argc != 3) {
exit(-1);
bzero(&s_addr, sizeof(s_addr));
s_addr.sin_family = AF_INET;
s_addr.sin_addr.s_addr = inet_addr(argv[1]);
s_addr.sin_port = htons(atoi(argv[2]));
printf("setsockopt error\n");
57
exit(-1);
while(1) {
sndBuffer[n-1] = '\0';
exit(-3);
close(sd);
</ 소스 >
< 소스 UDPreader.c>
//echo_client_UDPbcast.c
58
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <errno.h>
int sd;
char rcvBuffer[BUFSIZ];
int n, n_send;
int addr_len;
int status;
int on = 1;
if(argc != 2) {
exit(-1);
bzero(&s_addr, sizeof(s_addr));
59
s_addr.sin_family = AF_INET;
s_addr.sin_addr.s_addr = INADDR_ANY;
s_addr.sin_port = htons(atoi(argv[1]));
exit(-2);
while(1) {
addr_len = sizeof(s_addr);
&addr_len)) < 0) {
exit(-3);
rcvBuffer[n] = '\0';
break;
rcvBuffer);
close(sd);
60
</ 소스 >
61
PART 3 다중 접속 서버 구현하기
7 장 멀티프로세싱 방식의 다중 접속 서버
7.2 fork 함수
< 소스 fork_test.c>
//fork_test.c
#include <stdio.h>
main( )
int pid;
int a = 10;
int b = 20;
a = a + 1;
pid = fork( );
if(pid > 0) {
a = a + 1;
printf("PARENT");
} else if(pid == 0) {
b = b + 1;
printf("CHILD");
62
}
</ 소스 >
< 소스 echo_server_fork.c>
//echo_server_fork.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include <sys/socket.h>
void do_echo(int);
main( )
int len;
pid_t pid;
63
memset(&s_addr, 0, sizeof(s_addr));
s_addr.sin_addr.s_addr = htonl(INADDR_ANY);
s_addr.sin_family = AF_INET;
s_addr.sin_port = htons(PORT);
return -1;
if(listen(listenSock, 5) == -1) {
printf("listen Fail\n");
return -1;
while(1) {
len = sizeof(c_addr);
return -1;
close(connSock);
continue;
64
} else if(pid == 0 ) {
close(listenSock);
do_echo(connSock);
void
do_echo(int connSock) {
int n;
char rcvBuffer[BUFSIZ];
printf("child\n");
exit(0);
</ 소스 >
< 소스 sigact.c>
#include <stdio.h>
#include <signal.h>
65
struct sigaction act_new;
void
sig_handler(int signo)
11
int main(void)
act_new.sa_handler = sig_handler;
sigemptyset(&act_new. sa_mask);
act_new.sa_flags = 0;
while(1)
sleep(1);
</ 소스 >
66
7.4.2 wait 함수로 자식 프로세스의 종료 상태 확인
< 소스 wait_sigchld.c>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/wait.h>
void do_child(void);
void do_parent(void);
void
sighandler(int n)
chld_pid = wait(&stat);
17
if(WIFEXITED(stat)) {
} else if(WIFSIGNALED(stat)) {
} else if(WIFSTOPPED(stat)) {
67
}
26
exit(1);
int
main( )
int pid;
sigset.sa_handler = sighandler;
sigset.sa_flags = 0;
sigemptyset(&sigset.sa_mask);
if((pid = fork( )) == 0) {
do_child( );
do_parent( );
void
do_child( )
exit(100);
68
}
void do_parent( )
sleep(10);
</ 소스 >
7.4.3 좀비 프로세스의 생성 방지
< 소스 echo_server_fork_sig.c>
//echo_server_fork_sig.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <signal.h>
#include <sys/wait.h>
void do_echo(int);
void sigHandler(int);
main( )
69
int connSock, listenSock;
int len;
pid_t pid;
int state;
act.sa_handler = sigHandler;
sigemptyset(&act.sa_mask);
act.sa_flags=0;
if(state != 0) {
printf("signal error\n");
exit(1);
memset(&s_addr, 0, sizeof(s_addr));
s_addr.sin_addr.s_addr = htonl(INADDR_ANY);
s_addr.sin_family = AF_INET;
s_addr.sin_port = htons(PORT);
70
if(bind(listenSock, (struct sockaddr *) &s_addr, sizeof(s_addr)) == -1) {
return -1;
if(listen(listenSock, 5) == -1) {
printf("listen Fail\n");
return -1;
while(1) {
len = sizeof(c_addr);
printf("accept error\n");
return -1;
close(connSock);
continue;
} else if(pid == 0 ) {
printf("child creat\n");
close(listenSock);
71
do_echo(connSock);
void
do_echo(int connSock)
int n;
char rcvBuffer[BUFSIZ];
81
printf("child(%d)\n", n);
exit(1);
void
sigHandler(int sig)
int pid;
int status;
pid = wait(&status);
72
}
</ 소스 >
7.5.1 서버 프로그램
< 소스 talk_server.c>
//talk_server.c
// $ talk_server port#
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <signal.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
void do_keyboard(int);
void do_socket(int);
pid_t pid;
int
73
int len;
if(argc < 2) {
return -1;
return -1;
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
server_addr.sin_port = htons(atoi(argv[1]));
40
return -1;
listen(listenSock, 1);
len = sizeof(client_addr);
74
if((connSock=accept(listenSock,(struct sockaddr *) &client_addr, &len))<0) {
return -1;
printf("fork error\n");
return -1;
do_keyboard(connSock);
} else if(pid == 0) {
do_socket(connSock);
close(listenSock);
close(connSock);
void
do_keyboard(int connSock)
int n;
char sbuf[BUFSIZ];
75
if(write(connSock, sbuf, n) != n) {
if(strncmp(sbuf, quit, 4) == 0) {
kill(pid, SIGQUIT);
break;
void
do_socket(int connSock)
int n;
char rbuf[BUFSIZ];
while(1) {
rbuf[n] = '\0';
printf("%s", rbuf);
if(strncmp(rbuf, quit, 4) == 0) {
kill(getppid( ), SIGQUIT);
break;
76
}
</ 소스 >
< 소스 talk_client.c>
//talk_client.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <signal.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
void do_keyboard(int);
void do_socket(int);
pid_t pid;
int
77
int connSock;
char *serverAddr;
int serverPort;
int len;
if(argc != 3) {
return -1;
} else {
serverAddr = argv[1];
serverPort = atoi(argv[2]);
return -1;
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = inet_addr(serverAddr);
server_addr.sin_port = htons(serverPort);
78
printf("talk Client Can't connect \n");
return -1;
printf("fork error\n");
return -1;
do_keyboard(connSock);
} else if(pid == 0) {
do_socket(connSock);
close(connSock);
void
do_keyboard(int connSock)
int n;
char sbuf[BUFSIZ];
if(write(connSock, sbuf, n) != n) {
79
}
if(strncmp(sbuf, quit, 4) == 0) {
kill(pid, SIGQUIT);
break;
void
do_socket(int connSock)
int n;
char rbuf[BUFSIZ];
while(1) {
rbuf[n] = '\0';
printf("%s", rbuf);
if(strncmp(rbuf, quit, 4) == 0) {
kill(getppid( ), SIGQUIT);
break;
80
}
</ 소스 >
81
8 장 멀티스레딩 방식의 다중 접속 서버
< 소스 pthread_func.c>
//pthread_func.c
#include <stdio.h>
#include <pthread.h>
int
int sts;
pthread_t thread_id;
void *t_return;
exit(1);
sleep(3);
82
printf("main function exit\n");
return 0;
int i;
while(1) {
sleep(1);
printf("thread executing....\n");
</ 소스 >
< 소스 pthread_join_func.c>
//pthread_join_func.c
#include <stdio.h>
#include <pthread.h>
void *
do_sum(void *data)
int i;
int sum = 0;
83
int max = *((int *)data);
sum = sum + i;
sleep(1);
int
main( )
int thr_id;
pthread_t p_thread[3];
int status;
int a = 4;
int b = 5;
int c = 6;
84
pthread_join(p_thread[0], (void **) &status);
printf("programing is end\n");
return 0;
</ 소스 >
< 소스 pthread_mutex.c>
//pthread_mutex.c
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
int ncount;
int i;
85
printf("sum1 : %d\n", ncount);
pthread_mutex_lock(&mutex);
ncount ++;
pthread_mutex_unlock(&mutex);
sleep(1);
int i;
pthread_mutex_lock(&mutex);
ncount ++;
pthread_mutex_unlock(&mutex);
sleep(1);
int main( )
86
int thr_id;
pthread_t p_thread[2];
int status;
int a;
ncount = 1;
a = 9;
sleep(1);
a = 10;
status = pthread_mutex_destroy(&mutex);
printf("programing is end");
return 0;
</ 소스 >
< 소스 echo_server_pthread.c>
87
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <pthread.h>
main( )
int len;
pthread_t pthread1;
int thr_id;
23
memset(&s_addr, 0, sizeof(s_addr));
s_addr.sin_addr.s_addr = htonl(INADDR_ANY);
s_addr.sin_family = AF_INET;
s_addr.sin_port = htons(PORT);
88
if(bind(listenSock, (struct sockaddr *) &s_addr, sizeof(s_addr)) == -1) {
return -1;
if(listen(listenSock, 5) == -1) {
printf("listen Fail\n");
return -1;
while(1) {
len = sizeof(c_addr);
void *
do_echo(void *data)
int n;
char rcvBuffer[BUFSIZ];
89
while((n = read(connSock, rcvBuffer, sizeof(rcvBuffer))) != 0) {
</ 소스 >
8.5.1 서버 프로그램
< 소스 talk_server_pthread.c>
//talk_server_pthread.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <signal.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pthread.h>
pthread_t pid[2];
90
int
int thr_id;
int status;
int len;
if(argc < 2) {
return -1;
return -1;
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
server_addr.sin_port = htons(atoi(argv[1]));
91
if(bind(listenSock, (struct sockaddr *) &server_addr, sizeof(server_addr))<0){
return -1;
listen(listenSock, 1);
len = sizeof(client_addr);
return -1;
close(listenSock);
close(connSock);
void *
do_keyboard(void *data)
92
{
int n;
char sbuf[BUFSIZ];
if(write(connSock, sbuf, n) != n) {
if(strncmp(sbuf, quit, 4) == 0) {
pthread_kill(pid[1], SIGINT);
break;
void *
do_socket(void *data)
int n;
char rbuf[BUFSIZ];
while(1) {
rbuf[n] = '\0';
93
printf("%s", rbuf);
if(strncmp(rbuf, quit, 4) == 0) {
pthread_kill(pid[0], SIGINT);
break;
</ 소스 >
< 소스 talk_client_pthread.c>
//talk_client_pthread.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <signal.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pthread.h>
94
pthread_t pid[2];
int
int connSock;
char *serverAddr;
int serverPort;
int len;
if(argc != 3) {
return -1;
} else {
serverAddr = argv[1];
serverPort = atoi(argv[2]);
return -1;
95
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = inet_addr(serverAddr);
server_addr.sin_port = htons(serverPort);
return -1;
close(connSock);
void *
do_keyboard(void *data)
int n;
char sbuf[BUFSIZ];
96
if(write(connSock, sbuf, n) != n) {
if(strncmp(sbuf, quit, 4) == 0) {
pthread_kill(pid[1],SIGINT);
break;
void *
do_socket(void *data)
int n;
char rbuf[BUFSIZ];
while(1) {
rbuf[n] = '\0';
printf("%s", rbuf);
if(strncmp(rbuf, quit, 4) == 0) {
pthread_kill(pid[0],SIGINT);
break;
97
}
< 소스 >
98
9 장 멀티플렉싱 방식의 다중 접속 서버
< 소스 echo_server_select.c>
//echo_server_select.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include <sys/socket.h>
int numClient=0;
int clientSock[MAX];
int getMaxfd(int);
main( )
int len, i, n;
char rcvBuffer[BUFSIZ];
int maxfd;
99
fd_set read_fds;
memset(&s_addr, 0, sizeof(s_addr));
s_addr.sin_addr.s_addr = htonl(INADDR_ANY);
s_addr.sin_family = AF_INET;
s_addr.sin_port = htons(PORT);
return -1;
if(listen(listenSock, 5) == -1) {
printf("listen Fail\n");
return -1;
while(1) {
maxfd = getMaxfd(listenSock) + 1;
FD_ZERO(&read_fds);
FD_SET(listenSock, &read_fds);
100
for(i = 0; i < numClient; i++)
FD_SET(clientSock[i], &read_fds);
printf("select error\n");
exit(-1);
printf("waiting---\n");
if(FD_ISSET(listenSock, &read_fds)) {
clientSock[numClient++] = connSock;
if(FD_ISSET(clientSock[i], &read_fds) ) {
if((n=read(clientSock[i], rcvBuffer,sizeof(rcvBuffer)))!=0){
rcvBuffer[n]='\0';
} else {
printf("EOF\n");
close(clientSock[i]);
if(i != numClient-1)
clientSock[i] = clientSock[numClient-1];
101
numClient--;
continue;
int
getMaxfd(int n)
int max = n;
int i;
max = clientSock[i];
return max;
</ 소스 >
9.4.1 서버 프로그램
102
< 소스 talk_server_select.c>
//talk_server_select.c
#include stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include <sys/socket.h>
int numClient=0;
int len, i, n;
int maxfd;
if(argc < 2) {
return -1;
103
fd_set read_fds;
28
memset(&s_addr, 0, sizeof(s_addr));
s_addr.sin_addr.s_addr = htonl(INADDR_ANY);
s_addr.sin_family = AF_INET;
s_addr.sin_port = htons(atoi(argv[1]));
return -1;
if(listen(listenSock, 1) == -1) {
printf("listen Fail\n");
return -1;
while(1) {
maxfd = connSock + 1;
FD_ZERO(&read_fds);
FD_SET(0, &read_fds);
FD_SET(connSock, &read_fds);
104
if(select(maxfd, &read_fds, NULL, NULL, NULL) < 0) {
printf("select error\n");
exit(-1);
printf("server waiting---\n");
if(FD_ISSET(0, &read_fds)) {
if(write(connSock, sbuf, n) != n) {
if(strncmp(sbuf, quit, 4) == 0) {
break;
if(FD_ISSET(connSock, &read_fds)) {
if((n=read(connSock, rcvBuffer,sizeof(rcvBuffer)))!=0){
rcvBuffer[n]='\0';
printf("receive[%s]\n", rcvBuffer);
if(strncmp(rcvBuffer, quit, 4) == 0) {
break;
105
}
</ 소스 >
< 소스 talk_client_select.c>
//talk_client_select.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include <sys/socket.h>
int numClient=0;
int connSock;
int len, i, n;
int maxfd;
106
if(argc < 3) {
return -1;
fd_set read_fds;
memset(&s_addr, 0, sizeof(s_addr));
s_addr.sin_addr.s_addr = inet_addr(argv[1]);
s_addr.sin_family = AF_INET;
s_addr.sin_port = htons(atoi(argv[2]));
return -1;
while(1) {
maxfd = connSock + 1;
FD_ZERO(&read_fds);
FD_SET(0, &read_fds);
FD_SET(connSock, &read_fds);
107
if(select(maxfd, &read_fds, NULL, NULL, NULL) < 0) {
printf("select error\n");
exit(-1);
printf("client waiting---\n");
if(FD_ISSET(0, &read_fds)) {
if (write(connSock, sbuf, n) != n) {
if(strncmp(sbuf, quit, 4) == 0) {
break;
if(FD_ISSET(connSock, &read_fds)) {
rcvBuffer[n]='\0';
printf("receive[%s]\n", rcvBuffer);
if(strncmp(rcvBuffer, quit, 4) == 0) {
break;
108
}
</ 소스 >
109
10 장 MFC 로 talk 프로그램 구현하기
10.1.2 소켓 객체 CSocket::CTalkClientSocket의 생성
< 소스 TalkClientSocket.h>
#pragma once
// CTalkClientSocket 명령 대상입니다 .
classCTalkClientDlg; --①
public:
virtual ~CTalkClientSocket( );
public:
CTalkClientDlg*m_pTalkClientDlg; --③
public:
};
</ 소스 >
110
< 소스 TalkClientSocket.cpp>
// TalkClientSocket.cpp : 구현 파일입니다 .
//
#include "stdafx.h"
#include "TalkClient.h"
#include "TalkClientSocket.h"
// CTalkClientSocket
CTalkClientSocket::~CTalkClientSocket( )
// CTalkClientSocket 멤버 함수
m_pTalkClientDlg->ProcessReceive( ); --④
CSocket::OnReceive(nErrorCode);
111
{
m_pTalkClientDlg->ProcessClose( ); --⑤
CSocket::OnClose(nErrorCode);
</ 소스 >
< 소스 TalkClientDlg.h>
// TalkClientDlg.h : 헤더 파일
#pragma once
#include "afxwin.h"
#include "afxcmn.h"
// CTalkClientDlg 대화 상자
// 생성입니다 .
public:
// 대화 상자 데이터입니다 .
protected:
112
virtual void DoDataExchange(CDataExchange* pDX);// DDX/DDV 지원입니다 .
// 구현입니다 .
protected:
HICON m_hIcon;
// 생성된 메시지 맵 함수
DECLARE_MESSAGE_MAP( )
public:
public:
CEdit m_edit_talk;
CIPAddressCtrl m_ip_address;
CEdit m_edit_port;
CButton m_button_send;
CButton m_button_connect;
CButton m_button_disconnect;
public:
public:
113
void SetButtonStatus(bool, bool, bool);
void ProcessReceive(void);
};
</ 소스 >
< 소스 TalkClientDlg.cpp>
// TalkClientDlg.cpp : 구현 파일
#include "stdafx.h"
#include "TalkClient.h"
#include "TalkClientDlg.h"
BOOL CTalkClientDlg::OnInitDialog( )
CDialog::OnInitDialog( );
if(pSysMenu != NULL)
CString strAboutMenu;
114
strAboutMenu.LoadString(IDS_ABOUTBOX);
if(!strAboutMenu.IsEmpty( ))
pSysMenu->AppendMenu(MF_SEPARATOR);
경우에는
TCHARstrIP[20];
TCHARstrPort[10];
115
UINTnPort;
m_ip_address.GetWindowTextA(strIP, 20);
m_edit_port.GetWindowTextA(strPort, 10);
nPort = atoi(strPort);
if(!m_pTalkClientSocket->Create( )) {
return;
m_list_box.AddString(_T("Socket Create...."));
if(!m_pTalkClientSocket->Connect(strIP, nPort)){
m_list_box.AddString(_T("Fail to connect"));
return;
m_list_box.AddString(_T("Success to Connect...."));
m_button_send.EnableWindow(bSend);
m_button_connect.EnableWindow(bConnect);
116
m_button_disconnect.EnableWindow(bDisconnect);
TCHARstrBuf[100];
m_edit_talk.GetWindowTextA(strBuf, 100);
m_list_box.SetWindowTextA(strBuf);
m_edit_talk.SetWindowTextA(_T(""));
intnRead;
TCHARrcvBuffer[1024];
strBuffer.Format("%s", rcvBuffer);
m_list_box.AddString(strBuffer.Left(nRead));
117
{
m_pTalkClientSocket->Close( );
delete m_pTalkClientSocket;
m_list_box.AddString(_T("Close socket"));
m_list_box.AddString(_T("Server Close"));
m_pTalkClientSocket->Close( );
delete m_pTalkClientSocket;
m_list_box.AddString(_T("Connection Close"));
</ 소스 >
10.2 서버 프로그램
< 소스 ListenSocket.h>
#pragma once
118
// CListenSocket 명령 대상입니다 .
public:
virtual ~CListenSocket( );
public:
public:
};
</ 소스 >
< 소스 ListenSocket.cpp>
// ListenSocket.cpp : 구현 파일입니다 .
//
#include "stdafx.h"
#include "TalkServer.h"
#include "ListenSocket.h"
// CListenSocket
119
CListenSocket::CListenSocket(CTalkServerDlg* pTalkServerDlg) --②
m_pTalkServerDlg = pTalkServerDlg; ③
CListenSocket::~CListenSocket( )
// CListenSocket 멤버 함수
m_pTalkServerDlg->ProcessAccept( ); --④
CSocket::OnAccept(nErrorCode);
</ 소스 >
< 소스 ServiceSocket.h>
#pragma once
// CServiceSocket 명령 대상입니다 .
120
{
public:
virtual ~CServiceSocket( );
public:
public:
};
</ 소스 >
< 소스 ServiceSocket.cpp>
// ServiceSocket.cpp : 구현 파일입니다 .
#include "stdafx.h"
#include "TalkServer.h"
#include "ServiceSocket.h"
// CServiceSocket
m_pTalkServerDlg = pTalkServerDlg; ③
CServiceSocket::~CServiceSocket( )
121
{
// CServiceSocket 멤버 함수
m_pTalkServerDlg->ProcessReceive(this); --④
CSocket::OnReceive(nErrorCode);
m_pTalkServerDlg->ProcessClose( ); --⑤
CSocket::OnClose(nErrorCode);
</ 소스 >
< 소스 TalkServerDlg.h>
// TalkServerDlg.h : 헤더 파일
#pragma once
#include "afxwin.h"
122
// CTalkServerDlg 대화 상자
// 생성입니다 .
public:
// 대화 상자 데이터입니다 .
protected:
// 구현입니다 .
protected:
HICON m_hIcon;
// 생성된 메시지 맵 함수
DECLARE_MESSAGE_MAP( )
public:
CListenSocket* m_pListenSocket;
123
public:
CEdit m_edit_talk;
CEdit m_edit_port;
CButton m_button_send;
CButton m_button_start;
CButton m_button_stop;
public:
void ProcessReceive(CServiceSocket*);
void ProcessClose(void);
public:
};
</ 소스 >
< 소스 TalkServerDlg.cpp>
// TalkServerDlg.cpp : 구현 파일
//
#include "stdafx.h"
#include "TalkServer.h"
#include "TalkServerDlg.h"
124
BOOL CTalkServerDlg::OnInitDialog( )
CDialog::OnInitDialog( );
if(pSysMenu != NULL)
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if(!strAboutMenu.IsEmpty( ))
pSysMenu->AppendMenu(MF_SEPARATOR);
경우에는
125
SetIcon(m_hIcon, FALSE);// 작은 아이콘을 설정합니다 .
UINTnPort;
TCHARstrPort[10];
m_edit_port.GetWindowTextA(strPort, 10);
nPort = atoi(strPort);
if(!m_pListenSocket->Create(nPort)) {
return;
if(!m_pListenSocket->Listen( )) {
126
return;
m_list_talk.AddString("Listen Socket....");
m_pListenSocket->Accept(*m_pServiceSocket);
m_list_talk.AddString("Connection Accept....");
intnRead;
TCHARstrRecvBuffer[1024];
CStringstrBuffer = _T("");
strBuffer.Format("%s", strRecvBuffer);
m_list_talk.AddString(strBuffer.Left(nRead));
127
}
TCHARstrSndBuffer[1024];
m_edit_talk.GetWindowTextA(strSndBuffer, 1024);
m_pServiceSocket->Send(strSndBuffer, (int)strlen(strSndBuffer));
m_edit_talk.SetWindowTextA(_T(""));
m_button_send.EnableWindow(bSend);
m_button_start.EnableWindow(bStart);
m_button_stop.EnableWindow(bStop);
m_pListenSocket->Close( );
m_pServiceSocket->Close( );
128
m_list_talk.AddString(_T("Close Socket"));
delete m_pListenSocket;
delete m_pServiceSocket;
m_pServiceSocket->Close( );
delete m_pServiceSocket;
</ 소스 >
129
PART 4 TCP 내부 동작과 Raw 소켓
11 장 TCP 내부 동작
11.1 TCP 상태 변화
11.1.1 연결 준비 단계
< 소스 port_stat.c>
//port_stat.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include <sys/socket.h>
int len;
if(argc != 2) {
exit -1;
130
s_socket = socket(PF_INET, SOCK_STREAM, 0);
memset(&s_addr, 0, sizeof(s_addr));
s_addr.sin_addr.s_addr = htonl(INADDR_ANY);
s_addr.sin_family = AF_INET;
s_addr.sin_port = htons(atoi(argv[1]));
return -1;
if(listen(s_socket, 5) == -1) {
printf("listen Fail\n");
return -1;
while(1) {
len = sizeof(c_addr);
</ 소스 >
131
11.2 TCP 소켓 옵션
< 소스 sock_opt.c>
//sock_opt.c
#include <sys/socket.h>
#include <stdio.h>
int
main( )
int sock;
struct sock_opts {
int opt_level;
int opt_name;
} sock_opts[ ] = {
132
{ NULL, 0, 0 }
};
len = sizeof(val);
35
</ 소스 >
133
12 장 Raw 소켓
< 소스 cksum_in.c>
unsigned short
while(nleft > 1) {
sum += *w++;
nleft -= 2;
if(nleft == 1) {
sum += answer;
134
sum = (sum & 0xffff) + (sum >> 16);
return (sum==0xffff)?sum:~sum;
</ 소스 >
< 소스 read_packet.c>
// read_packet.c
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <netinet/in.h>
#include <netdb.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <sys/socket.h>
main( )
int sd;
int len;
135
struct tcphdr *rx_tcph;
exit(-1);
while(1) {
bzero(rx_packet, rx_packet_size);
len = sizeof(local);
printf("recvfrom error\n");
exit(-2);
print_ip(rx_iph);
136
print_tcp(rx_tcph);
close(sd);
void
printf("[IP HEADER] VER: %1u HL : %2u Protocol : %3u ", iph->version, iph->ihl,
iph->protocol);
void
printf("[TCP HEADER] src port: %5u dest port : %5u ", ntohs(tcph->source),
ntohs(tcph->dest));
(tcph->urg == 1)?printf("U"):printf("-");
(tcph->ack == 1)?printf("A"):printf("-");
(tcph->psh == 1)?printf("P"):printf("-");
(tcph->rst == 1)?printf("R"):printf("-");
(tcph->syn == 1)?printf("S"):printf("-");
137
(tcph->fin == 1)?printf("F"):printf("-");
printf("\n\n");
</ 소스 >
< 소스 port_scan_sys.c>
//syn_port_scan.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netinet/in.h>
#include <netdb.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <sys/socket.h>
#define START_PORT 80
#define END_PORT 90
struct pseudohdr {
char zero;
138
unsigned char protocol;
};
int portNum;
if(argc < 2) {
exit(-1);
h = gethostbyname(argv[1]);
if(!h) {
printf("gethostbyname error\n");
return 4;
139
printf("port %d scanning..", portNum);
scan_syn_port(target, portNum);
int sd;
int on = 1;
int len;
pseudohdr);
140
iph = (struct iphdr *)(tx_packet);
tcphdr));
78
memset(tx_packet, 0, tx_packet_size);
d_addr.s_addr = target;
s_addr.s_addr = inet_addr(LOCAL_IP);
pseudoh->s_addr = s_addr.s_addr;
pseudoh->d_addr = d_addr.s_addr;
pseudoh->protocol = IPPROTO_TCP;
pseudoh->zero = 0;
tcph->source = htons(LOCAL_PORT);
tcph->dest = htons(port);
141
tcph->seq = htons(random()%time(NULL));
tcph->ack_seq = 0;
tcph->doff = 5;
tcph->res1 = 0;
tcph->fin = 0;
tcph->syn = 1;
tcph->rst = 0;
tcph->psh = 0;
tcph->ack = 0;
tcph->urg = 0;
tcph->window = htons(1024);
iph->ihl = 5;
iph->version = 4;
iph->tos = 0;
iph->id = 0;
iph->frag_off = 0;
iph->ttl = IPDEFTTL;
iph->protocol = IPPROTO_TCP;
iph->saddr = s_addr.s_addr;
iph->daddr = d_addr.s_addr;
142
remote.sin_family = PF_INET;
remote.sin_addr = d_addr;
remote.sin_port = htons(port);
remote.sin_port = 0;
(tcph->urg == 1)?printf("U"):printf("-");
(tcph->ack == 1)?printf("A"):printf("-");
(tcph->psh == 1)?printf("P"):printf("-");
(tcph->rst == 1)?printf("R"):printf("-");
(tcph->syn == 1)?printf("S"):printf("-");
(tcph->fin == 1)?printf("F"):printf("-");
){
143
if((ntohs(tcph->source) == ntohs(rx_tcph->dest)) && (ntohs(tcph->dest) ==
ntohs(rx_tcph->source))){
(rx_tcph->urg == 1)?printf("U"):printf("-");
(rx_tcph->ack == 1)?printf("A"):printf("-");
(rx_tcph->psh == 1)?printf("P"):printf("-");
(rx_tcph->rst == 1)?printf("R"):printf("-");
(rx_tcph->syn == 1)?printf("S"):printf("-");
(rx_tcph->fin == 1)?printf("F"):printf("-");
>s_name);
} else if (rx_tcph->rst == 1) {
printf(" *\n");
} else {
break;
close(sd);
144
unsigned short
while(nleft > 1) {
sum += *w++;
nleft -= 2;
if(nleft == 1) {
sum += answer;
return(sum==0xffff)?sum:~sum;
145
</ 소스 >
< 소스 my_ping.c>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in_systm.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#include <signal.h>
void sig_alrm(int);
void send_msg(void);
void handlePing(void);
int sd;
pid_t pid;
int nsent = 0;
146
int salen;
if(argc != 2) {
exit(-1);
sasend.sin_family = AF_INET;
sasend.sin_addr.s_addr = inet_addr(argv[1]);
salen = sizeof(sasend);
handlePing( );
void
handlePing(void)
char rbuf[1500];
fd_set readfd;
147
struct iphdr *iph;
double rtt;
signal(SIGALRM, sig_alrm);
exit(-1);
sig_alrm(SIGALRM);
for( ;;) {
printf("read error\n");
exit (-1);
hlen = iph->ihl * 4;
if(iph->protocol != IPPROTO_ICMP)
return;
148
if(iph->saddr == sasend.sin_addr.s_addr) {
if(icmp->icmp_type == ICMP_ECHOREPLY) {
if(icmp->icmp_id != pid)
return;
gettimeofday(&tvrecv, NULL);
tv_sub(&tvrecv, tvsend);
void
sig_alrm(int signo)
send_msg( );
149
alarm(1);
return;
void
send_msg(void)
int len;
char sendbuf[1500];
icmp->icmp_type = ICMP_ECHO;
icmp->icmp_code = 0;
icmp->icmp_id = pid;
icmp->icmp_seq = nsent++;
len = 8 + datalen;
icmp->icmp_cksum = 0;
150
sendto(sd, sendbuf, len, 0, (struct sockaddr *)&sasend, salen);
void
--out->tv_sec;
out->tv_usec += 1000000;
out->tv_sec -= in->tv_sec;
unsigned short
while(nleft > 1) {
sum += *w++;
nleft -= 2;
151
}
if(nleft == 1) {
sum += answer;
return(sum==0xffff)?sum:~sum;
</ 소스 >
152
PART 5 프로젝트로 실습하기
13 장 프로젝트 - 웹 서버
13.3 웹 서버의 구현
< 소스 webClient.c>
//webClient.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
char *haddr;
char buf[BUF_LEN+1];
int port;
if(argc==3) {
153
port=80;
} else if(argc==4) {
port=atoi(argv[3]);
} else {
return -1;
haddr=argv[1];
return -1;
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family=AF_INET;
server_addr.sin_addr.s_addr=inet_addr(haddr);
server_addr.sin_port=htons(port);
return -1;
154
memset(buf, 0, sizeof(buf));
printf("%s", buf);
memset(buf, 0, sizeof(buf));
close(s);
</ 소스 >
< 소스 webServer_fork.c>
//webServer_fork.c
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/resource.h>
#include <netinet/in.h>
#include <signal.h>
#include <sys/stat.h>
155
#define CODE200 200
void do_web(int);
int log_fd;
int
int status;
int i;
int pid;
if(argc != 2){
return -1;
156
}
if(fork( ) != 0)
resourceLimit.rlim_max = 0;
close(i);
port=atoi(argv[1]);
66
memset(&s_addr, 0, sizeof(s_addr));
s_addr.sin_family = AF_INET;
157
s_addr.sin_addr.s_addr = htonl(INADDR_ANY);
s_addr.sin_port = htons(port);
listen(s_sock, 10);
while(1){
len = sizeof(c_addr);
} else if(pid == 0) {
close(s_sock);
do_web(c_sock);
} else {
close(c_sock);
void
do_web(int c_sock)
158
{
int len;
int len_out;
int n, i;
char *p;
char file_name[20];
char ext[20];
struct {
char *ext;
char *filetype;
} extensions [ ] = {
{"gif", "image/gif" },
{"jpg", "image/jpeg"},
{"jpeg","image/jpeg"},
159
{"png", "image/png" },
{"zip", "image/zip" },
{"gz", "image/gz" },
{"tar", "image/tar" },
{"htm", "text/html" },
{"html","text/html" },
{0,0} };
memset(rcvBuf, 0, sizeof(rcvBuf));
web_log(ERROR, "ERROR", "can not receive data from web browser", n);
if(!strcmp(p, "/"))
else
strcpy(c_type, "text/plain");
160
len = strlen(extensions[i].ext);
strcpy(c_type, extensions[i].filetype);
break;
code = CODE404;
strcpy(phrase, PHRASE404);
// send Header
if(fd >=0 ) {
161
}
close(c_sock);
exit(-1);
void
int log_fd;
char buf[BUFSIZ];
if(type == LOG) {
close(log_fd);
162
}
</ 소스 >
< 소스 webServer_thread.c>
//webServer_thread.c
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/resource.h>
#include <pthread.h>
#include <netinet/in.h>
#include <signal.h>
#include <sys/stat.h>
163
void *do_web(void *);
pthread_t tid;
int log_fd;
int
int status;
int i, res;
int pid;
if(argc != 2){
return -1;
if(fork( ) != 0)
164
(void)signal(SIGCLD, SIG_IGN); // ignore child death
resourceLimit.rlim_max = 0;
close(i);
port=atoi(argv[1]);
memset(&s_addr, 0, sizeof(s_addr));
s_addr.sin_family = AF_INET;
s_addr.sin_addr.s_addr = htonl(INADDR_ANY);
s_addr.sin_port = htons(port);
165
web_log(ERROR, "ERROR", "server cannot bind", 0);
listen(s_sock, 10);
while(1){
len = sizeof(c_addr);
85
void *
do_web(void *arg)
int len;
int len_out;
int n, i;
char *p;
166
char phrase[20] = "OK";
char file_name[20];
char ext[20];
struct {
char *ext;
char *filetype;
} extensions [ ] = {
{"gif", "image/gif" },
{"jpg", "image/jpeg"},
{"jpeg","image/jpeg"},
{"png", "image/png" },
{"zip", "image/zip" },
{"gz", "image/gz" },
{"tar", "image/tar" },
{"htm", "text/html" },
{"html","text/html" },
{0,0} };
memset(rcvBuf, 0, sizeof(rcvBuf));
167
if((n = read(c_sock, rcvBuf, BUFSIZ)) <= 0)
web_log(ERROR, "ERROR", "can not receive data from web browser", n);
if(!strcmp(p, "/"))
else
strcpy(c_type, "text/plain");
len = strlen(extensions[i].ext);
strcpy(c_type, extensions[i].filetype);
break;
code = CODE404;
168
strcpy(phrase, PHRASE404);
// send Header
if(fd >=0 ) {
close(c_sock);
void
169
int log_fd;
char buf[BUFSIZ];
if(type == LOG) {
pthread_mutex_lock(&mutex);
close(log_fd);
pthread_mutex_unlock(&mutex);
</ 소스 >
170
14 장 프로젝트 - 채팅 프로그램
14.2.1 서버 프로그램
< 소스 chat_server_select.c>
//chat_server_select.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/select.h>
#define MAX_CLIENT 10
#define INVALID_SOCK -1
int list_c[MAX_CLIENT];
171
struct sockaddr_in s_addr, c_addr;
int len;
int nfds = 0;
int i, j, n;
fd_set read_fds;
char chatData[CHATDATA];
int res;
if(argc < 2) {
exit(-1);
memset(&s_addr, 0, sizeof(s_addr));
s_addr.sin_addr.s_addr = htonl(INADDR_ANY);
s_addr.sin_family = AF_INET;
s_addr.sin_port = htons(atoi(argv[1]));
return -1;
172
printf("listen Fail\n");
return -1;
list_c[i] = INVALID_SOCK;
while(1) {
nfds = s_socket;
FD_ZERO(&read_fds);
FD_SET(s_socket, &read_fds);
if(list_c[i] != INVALID_SOCK) {
FD_SET(list_c[i], &read_fds);
nfds++;
if(select(nfds, &read_fds, (fd_set *)0, (fd_set *)0, (struct timeval *)0) < 0) {
printf("select error\n");
exit(1);
173
if(FD_ISSET(s_socket, &read_fds)) {
len = sizeof(c_addr);
res = pushClient(c_socket);
if(res < 0) {
close(c_socket);
} else {
89
memset(chatData, 0, sizeof(chatData));
if(list_c[i] != INVALID_SOCK)
popClient(list_c[i]);
174
break;
104
int
pushClient(int c_socket) {
int i;
if(list_c[i] == INVALID_SOCK) {
list_c[i] = c_socket;
return i;
if(i == MAX_CLIENT)
return -1;
int
popClient(int s)
175
{
int i;
close(s);
if(s == list_c[i] ) {
list_c[i] = INVALID_SOCK;
break;
return 0;
</ 소스 >
< 소스 chat_client_select.c>
//chat_client_select.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/select.h>
176
#define CHATDATA 1024
char nickname[20];
int c_socket;
int len;
char chatData[CHATDATA];
char buf[CHATDATA];
int nfds;
fd_set read_fds;
int n;
if(argc < 3) {
exit(-1);
c_addr.sin_addr.s_addr = inet_addr(argv[1]);
c_addr.sin_family = AF_INET;
177
c_addr.sin_port = htons(atoi(argv[2]));
scanf("%s", nickname);
return -1;
nfds = c_socket + 1;
while(1) {
FD_ZERO(&read_fds);
53
if(select(nfds, &read_fds, (fd_set *)0, (fd_set *)0, (struct timeval *)0) < 0) {
printf("select error\n");
exit(1);
if(FD_ISSET(c_socket, &read_fds)) {
memset(chatData, 0, sizeof(chatData));
178
write(1, chatData, n);
65
if(FD_ISSET(0, &read_fds)) {
memset(buf, 0, sizeof(buf));
break;
close(c_socket);
</ 소스 >
14.3.1 서버 프로그램
179
< 소스 chat_server_thread.c>
//chat_server_thread.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <pthread.h>
int pushClient(int);
int popClient(int);
pthread_t thread;
pthread_mutex_t mutex;
#define MAX_CLIENT 10
#define INVALID_SOCK -1
int list_c[MAX_CLIENT];
180
main(int argc, char *argv[ ])
int len;
int i, j, n;
int res;
if(argc < 2) {
exit(-1);
if(pthread_mutex_init(&mutex, NULL) != 0) {
return -1;
memset(&s_addr, 0, sizeof(s_addr));
s_addr.sin_addr.s_addr = htonl(INADDR_ANY);
s_addr.sin_family = AF_INET;
s_addr.sin_port = htons(atoi(argv[1]));
181
if(bind(s_socket, (struct sockaddr *)&s_addr, sizeof(s_addr)) == -1) {
return -1;
printf("listen Fail\n");
return -1;
list_c[i] = INVALID_SOCK;
while(1) {
len = sizeof(c_addr);
res = pushClient(c_socket);
if(res < 0) {
close(c_socket);
} else {
182
}
void *
do_chat(void *arg)
char chatData[CHATDATA];
int i, n;
while(1) {
memset(chatData, 0, sizeof(chatData));
if(list_c[i] != INVALID_SOCK) {
popClient(c_socket);
break;
183
int
pushClient(int c_socket) {
int i;
pthread_mutex_lock(&mutex);
if(list_c[i] == INVALID_SOCK) {
list_c[i] = c_socket;
pthread_mutex_unlock(&mutex);
return i;
pthread_mutex_unlock(&mutex);
if(i == MAX_CLIENT)
return -1;
122 }
int
popClient(int s)
int i;
close(s);
184
pthread_mutex_lock(&mutex);
if(s == list_c[i]) {
list_c[i] = INVALID_SOCK;
pthread_mutex_unlock(&mutex);
break;
pthread_mutex_unlock(&mutex);
return 0;
</ 소스 >
< 소스 chat_client_thread.c>
//chat_client_thread.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <pthread.h>
#include <signal.h>
185
#define CHATDATA 1024
char nickname[20];
int c_socket;
int len;
char chatData[CHATDATA];
char buf[CHATDATA];
int nfds;
fd_set read_fds;
int n;
if(argc < 3) {
exit(-1);
186
memset(&c_addr, 0, sizeof(c_addr));
c_addr.sin_addr.s_addr = inet_addr(argv[1]);
c_addr.sin_family = AF_INET;
c_addr.sin_port = htons(atoi(argv[2]));
scanf("%s", nickname);
return -1;
pthread_join(thread_1, NULL);
pthread_join(thread_2, NULL);
close(c_socket);
void *
do_send_chat(void *arg)
char chatData[CHATDATA];
187
char buf[CHATDATA];
int n;
while(1) {
memset(buf, 0, sizeof(buf));
pthread_kill(thread_2, SIGINT);
break;
void *
do_receive_chat(void *arg)
char chatData[CHATDATA];
int n;
while(1) {
188
memset(chatData, 0, sizeof(chatData));
</ 소스 >
< 소스 ListenSocket.h>
#pragma once
// CListenSocket 명령 대상입니다 .
public:
virtual ~CListenSocket( );
public:
public:
189
virtual void OnAccept(int nErrorCode); --④
};
</ 소스 >
< 소스 ListenSocket.cpp>
// ListenSocket.cpp : 구현 파일입니다 .
//
#include "stdafx.h"
#include "ChatServer.h"
#include "ListenSocket.h"
// CListenSocket
m_pChatServerDlg = pChatServerDlg; ③
CListenSocket::~CListenSocket( )
// CListenSocket 멤버 함수
190
{
m_pChatServerDlg->ProcessAccept( ); --④
CSocket::OnAccept(nErrorCode);
</ 소스 >
< 소스 ServiceSocket.h>
#pragma once
// CServiceSocket 명령 대상입니다 .
public:
virtual ~CServiceSocket( );
public:
public:
};
</ 소스 >
191
< 소스 ServiceSocket.cpp>
// ServiceSocket.cpp : 구현 파일입니다 .
//
#include "stdafx.h"
#include "ChatServer.h"
#include "ServiceSocket.h"
// CServiceSocket
m_pChatServerDlg = pChatServerDlg; ③
CServiceSocket::~CServiceSocket( )
// CServiceSocket 멤버 함수
m_pChatServerDlg->ProcessReceive( ); --④
192
CSocket::OnReceive(nErrorCode);
m_pChatServerDlg->ProcessClose( ); --⑤
CSocket::OnClose(nErrorCode);
</ 소스 >
< 소스 ChatServerDlg.h>
// ChatServerDlg.h : 헤더 파일
//
#pragma once
#include "afxwin.h"
// CChatServerDlg 대화 상자
193
// 생성입니다 .
public:
// 대화 상자 데이터입니다 .
protected:
// 구현입니다 .
protected:
HICON m_hIcon;
// 생성된 메시지 맵 함수
DECLARE_MESSAGE_MAP( )
public:
194
public:
CEdit m_edit_status; -- +
public:
public:
};
</ 소스 >
< 소스 ChatServerDlg.cpp>
BOOL CChatServerDlg::OnInitDialog( )
CDialog::OnInitDialog( );
195
CMenu* pSysMenu = GetSystemMenu(FALSE);
if(pSysMenu != NULL)
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if(!strAboutMenu.IsEmpty( ))
pSysMenu->AppendMenu(MF_SEPARATOR);
196
// TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다 .
charstrPort[10];
UINTuPort;
m_edit_port.GetWindowText(strPort, 10);
uPort = atoi(strPort);
if(!m_pListenSocket->Create(uPort)) {
return;
m_edit_status.SetWindowText(_T("Socket Create"));
if(!m_pListenSocket->Listen( )) {
m_edit_status.SetWindowText(_T("Fail to Listen"));
return;
m_edit_status.SetWindowText(_T("Listening Socket..."));
SetButtonStatus(FALSE, TRUE);
POSITIONpos = m_pServiceSocketList.GetHeadPosition( );
197
CServiceSocket* pClient;
while(pos != NULL) {
pClient->Close( );
delete pClient;
delete m_pListenSocket;
SetButtonStatus(TRUE, FALSE);
if(!m_pListenSocket->Accept(*m_pServiceSocket)) {
m_edit_status.SetWindowText(_T("Fail to Accept"));
return;
m_pServiceSocketList.AddTail(m_pServiceSocket);
TCHAR rcvBuffer[1024];
198
int nRead;
POSITIONpos = m_pServiceSocketList.GetHeadPosition( );
CServiceSocket* pClient;
while(pos != NULL) {
pClient->Send(rcvBuffer, nRead);
POSITION pos;
pos = m_pServiceSocketList.Find(pServiceSocket);
m_pServiceSocketList.RemoveAt(pos);
delete pServiceSocket;
m_edit_status.SetWindowText(_T("Client Disconnect"));
m_button_start.EnableWindow(bStart);
199
m_button_stop.EnableWindow(bStop);
</ 소스 >
200
15 장 프로젝트 - FTP 프로그램
15.2 파일 처리 관련 함수
< 소스 fileRead.c>
//fileRead.c
# include <stdio.h>
int c;
FILE *from;
if(argc != 2) {
exit(-1);
perror(argv[1]);
exit(1);
printf("%c", c);
201
fclose(from);
</ 소스 >
< 소스 fileRead_fgets.c>
//fileRead_fgets.c
#include <stdio.h>
char buf[BUFSIZ];
if(argc != 3) {
exit(-1);
perror(argv[1]);
exit(1);
perror(argv[2]);
exit(1);
202
while(fgets(buf, BUFSIZ, from) != NULL)
fputs(buf, to);
fclose(from);
fclose(to);
</ 소스 >
< 소스 fileRead_fread.c>
//fileRead_fread.c
#include <stdio.h>
char buf[BUFSIZ];
int n;
if(argc != 3) {
exit(-1);
perror(argv[1]);
203
exit(1);
perror(argv[2]);
exit(1);
fclose(from);
fclose(to);
</ 소스 >
< 소스 fileRead_read.c>
//fileRead_read.c
#include <stdio.h>
#include <sys/file.h>
char buf[BUFSIZ];
int n;
204
if(argc != 3) {
exit(-1);
perror(argv[1]);
exit(1);
perror(argv[2]);
exit(1);
close(from);
close(to);
</ 소스 >
205
< 소스 ftp_client.c>
//ftp_client.c
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <net/if.h>
#define PORTLEN 28
short cmdPort;
int cmdSock;
int dataSock;
char message[BUFSIZ];
struct _dataChannel {
char ip[STRLEN];
char chaIp[STRLEN];
char chaPort[STRLEN];
206
int c_sock;
} dataChannel;
int
if(argc == 3)
cmdPort = atoi(argv[2]);
else if(argc == 2)
cmdPort = 21;
else {
exit(-1);
cmdSock = makeConnection(argv[1]);
makeLogin( );
while(1) {
processCommand( );
close(cmdSock);
207
}
int
makeConnection(char *ip)
exit(-1);
memset(&s_addr, 0, sizeof(s_addr));
s_addr.sin_family = AF_INET;
s_addr.sin_addr.s_addr = inet_addr(ip);
s_addr.sin_port = htons(cmdPort);
exit(-1);
return (cmdSock);
makeLogin( )
208
char *pUser, *pPass;
int intCode;
char chaCode[STRLEN];
char sndBuf[BUFSIZ];
int n;
memset(pUser, 0, STRLEN);
memset(pPass, 0, STRLEN);
// make user
intCode = getCode(message);
if(intCode == 220) {
printf("User : ");
pUser[strlen(pUser) - 1] = '\0';
} else {
209
fprintf(stderr, "login error");
exit(-1);
// make password
intCode = getCode(message);
if(intCode == 331) {
} else {
exit(-1);
// Sucess Login
intCode = getCode(message);
if(intCode == 230) {
} else {
210
exit(-1);
free(pUser); free(pPass);
processCommand( )
char command[BUFSIZ];
char *pCommand;
int nCmd;
*pCommand = '\0';
strcpy(chaCmd, command);
strcpy(chaArg, "");
} else {
211
chaCmd[pCommand-command] = '\0';
if(!strcmp(chaCmd, "ls")) {
handle_ls(chaArg);
handle_get(chaArg);
handle_cd(chaArg);
handle_quit(chaArg);
exit(1);
handle_put(chaArg);
} else {
printf("command: ls|cd|get|put||hash|quit\n");
int
handle_quit(char chaArg[ ])
212
{
int intCode;
int n;
char chaCode[STRLEN];
char sndBuf[BUFSIZ];
char rcvBuf[BUFSIZ];
// send QUIT
memset(rcvBuf, 0, BUFSIZ);
intCode = getCode(rcvBuf);
close(cmdSock);
return (intCode);
int
handle_cd(char chaArg[ ])
int intCode;
int n;
213
char chaCode[STRLEN];
char sndBuf[BUFSIZ];
char rcvBuf[BUFSIZ];
// send CWD
memset(rcvBuf, 0, BUFSIZ);
intCode = getCode(rcvBuf);
return (intCode);
int
handle_put(char chaArg[ ])
char sndBuf[BUFSIZ];
char rcvBuf[BUFSIZ];
char chaCode[STRLEN];
int intCode;
int n, cnt;
int fsize;
// make PORT
214
make_ip( );
memset(rcvBuf, 0, BUFSIZ);
intCode = getCode(rcvBuf);
if(intCode != 200)
return (intCode);
if(!strcmp(chaArg, ""))
return -1;
return -1;
// send STOR
openDataChannel( );
memset(rcvBuf, 0, BUFSIZ);
cnt = 0;
215
while(1) {
cnt++;
intCode = getCode(rcvBuf);
if(intCode == 150) {
sndFile(chaArg);
} else {
return (intCode);
memset(rcvBuf, 0, BUFSIZ);
intCode = getCode(rcvBuf);
return (intCode);
int
handle_get(char chaArg[ ])
char sndBuf[BUFSIZ];
char rcvBuf[BUFSIZ];
char chaCode[STRLEN];
216
int intCode;
int n, cnt;
int fsize;
// send SIZE
memset(rcvBuf, 0, BUFSIZ);
intCode = getCode(rcvBuf);
if(intCode == 213) {
fsize = atoi(rcvBuf+3);
} else {
return (intCode);
return (intCode);
// make PORT
make_ip( );
217
sprintf(sndBuf, "PORT %s\r\n", dataChannel.chaPort);
memset(rcvBuf, 0, BUFSIZ);
intCode = getCode(rcvBuf);
// send RETR
openDataChannel( );
memset(rcvBuf, 0, BUFSIZ);
cnt = 0;
while(1) {
cnt++;
intCode = getCode(rcvBuf);
if(intCode == 150) {
rcvFile(fsize, chaArg);
218
} else {
return (intCode);
memset(rcvBuf, 0, BUFSIZ);
intCode = getCode(rcvBuf);
return (intCode);
sndFile(char *chaArg)
char sndBuf[BUFSIZ];
FILE *fp;
int n;
fp = fopen(chaArg, "r");
printf("\n");
fclose(fp);
219
close(dataChannel.c_sock);
char rcvBuf[BUFSIZ];
FILE *fp;
int nRecv = 0;
int n;
return (-1);
fwrite(rcvBuf, n, 1, fp);
nRecv += n;
printf("\n");
fclose(fp);
close(dataChannel.c_sock);
int
220
handle_ls(char chaArg[ ])
char sndBuf[BUFSIZ];
char rcvBuf[BUFSIZ];
char chaCode[STRLEN];
int intCode;
int n, cnt;
make_ip( );
memset(rcvBuf, 0, BUFSIZ);
intCode = getCode(rcvBuf);
if(intCode == 200) {
openDataChannel( );
} else
return intCode;
memset(rcvBuf, 0, BUFSIZ);
221
cnt = 0;
while(1) {
cnt++;
intCode = getCode(rcvBuf);
if(intCode == 150) {
rcvData( );
} else {
return intCode;
memset(rcvBuf, 0, BUFSIZ);
intCode = getCode(rcvBuf);
return intCode;
rcvData( )
int n = 0;
222
memset(rcvBuf, 0, BUFSIZ);
printf("%s", rcvBuf);
memset(rcvBuf, 0, BUFSIZ);
close(dataChannel.c_sock);
openDataChannel( )
int option = 8;
int optlen;
int len;
return;
optlen = sizeof(option);
memset(&data_addr, 0, sizeof(data_addr));
223
data_addr.sin_family = AF_INET;
data_addr.sin_addr.s_addr = inet_addr(dataChannel.ip);
data_addr.sin_port = htons(dataChannel.port);
return;
if(listen(dataSock, 1) == -1) {
return;
len = sizeof(c_addr);
-1) {
return;
make_ip( )
224
const int MAX_NIC = 10;
int nIF;
int s;
int i;
// make IP
ifc.ifc_len = sizeof(ifr);
ifc.ifc_ifcu.ifcu_req = ifr;
close(s);
strcpy(ip, localip);
225
for(i=0; i < nIF; i++) {
if(ifc.ifc_ifcu.ifcu_req[i].ifr_ifru.ifru_addr.sa_family != AF_INET) {
continue;
>sin_addr;
if(addr.s_addr == htonl(0x7f000001)) {
continue;
strcpy(ip, inet_ntoa(addr));
strcpy(dataChannel.ip, ip);
i = 0;
while(*(ip + i) != '\0') {
if(*(ip + i) == '.')
chaIP[i] = ',';
else
i++;
chaIP[i] = '\0';
strcpy(ip, chaIP);
226
strcpy(dataChannel.chaIp, ip);
// make port
srand(rand( ) % (time(NULL)));
dataChannel.port = np3;
strcat(chaPort1, chaPort2);
strcat(ip, chaPort1);
strcpy(dataChannel.chaPort, ip);
char chaCode[5];
chaCode[4] = '\0';
227
return (atoi(chaCode));
</ 소스 >
228