E D R , A S I H C RSS

Unix Socket Programming And Windows Implementation

ํŽ˜์ด์ง€์˜ ์ปจํ…์ธ ๋ฅผ ๋ณด์•„ํ•˜๋‹ˆ, ๋”ฐ๋กœ ํŽ˜์ด์ง€๋ฅผ ๋ฝ‘์•„๋‚ด๋„ ๋ ๊ฒƒ ๊ฐ™์•„ ๋ฌธ์„œ๊ตฌ์กฐ์กฐ์ • ํ•˜์˜€์Šต๋‹ˆ๋‹ค. ์›๋ž˜ ํŽ˜์ด์ง€ ์ด๋ฆ„์€ ๋ฐ๋ธ”์Šค์บ ํ”„2005/Socket Programming in Unix/Windows Implementation์˜€์Šต๋‹ˆ๋‹ค. - ์ž„์ธํƒ

์ฃผ์ œ : Socket Programming์˜ ๊ธฐ์ดˆ์ ์ธ ๋ถ€๋ถ„์„ ์•Œ์•„๋ณธ๋‹ค.

Contents

1. ๊ธฐ๋ณธ์ ์ธ ํ•จ์ˆ˜/๊ฐœ๋…๋“ค
1.1. Socket
1.1.1. domain:
1.1.2. type: ์„œ๋น„์Šค ํƒ€์ž…
1.1.3. protocol: ํ”„๋กœํ† ์ฝœ
1.2. ๋„คํŠธ์›Œํฌ ์ •๋ณด
1.2.1. sin_family: // ์ฃผ์†Œ์ฒด๊ณ„
1.2.2. sin_port:
1.2.3. sin_addr:
1.2.4. sin_zero:
2. Server ๊ฐ€ ๋  ํ”„๋กœ๊ทธ๋žจ์— ํ•„์š”ํ•œ ํ•จ์ˆ˜
2.1. Bind - socket๊ณผ ๋„คํŠธ์›Œํฌ ์ •๋ณด๋ฅผ ์—ฐ๊ฒฐํ•˜๋Š” Bind!!!
2.2. listen - client์˜ ์š”์ฒญ์„ ๊ธฐ๋‹ค๋ฆฐ๋‹ค!
2.3. accpet - client์˜ ์š”์ฒญ์„ ๋ฐ›์•„๋“ค์ธ๋‹ค!
3. Client ๊ฐ€ ๋  ํ”„๋กœ๊ทธ๋žจ์— ํ•„์š”ํ•œ ํ•จ์ˆ˜
3.1. connect - Server์— ์—ฐ๊ฒฐํ•œ๋‹ค.
4. ์ •๋ฆฌ์— ํ•„์š”ํ•œ ํ•จ์ˆ˜
4.1. close ํŒŒ์ผ์„ ๋‹ซ๋Š”๋‹ค.
5. server/client ๊ณตํ†ต - ์ž…์ถœ๋ ฅ ํ•จ์ˆ˜
5.1. send/write - ์ƒ๋Œ€์—๊ฒŒ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณด๋‚ธ๋‹ค.
5.2. recv/read - ์ƒ๋Œ€์—๊ฒŒ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›๋Š”๋‹ค.
6. โ€ป ์œˆ๋„์šฐ ๊ธฐ๋ฐ˜์—์„œ๋Š”...
7. server ์˜ˆ์ œ
8. ์‹ค์Šต
9. ์ฐธ๊ณ  ์‚ฌ์ดํŠธ


1. ๊ธฐ๋ณธ์ ์ธ ํ•จ์ˆ˜/๊ฐœ๋…๋“ค

1.1. Socket

โ€ป ์†Œ์ผ“์ด๋ž€?

~cpp 
#include <sys/types.h>
#include <sys/socket.h>

int socket(int domain, int type, int protocol);
// ์„ฑ๊ณต ์‹œ ํŒŒ์ผ ๋””์Šคํฌ๋ฆฝํ„ฐ, ์‹คํŒจ ์‹œ -1 ๋ฆฌํ„ด

1.1.1. domain:

PF_INET : ์ธํ„ฐ๋„ท ํ”„๋กœํ† ์ฝœ ์ฒด๊ณ„ ์‚ฌ์šฉ

PF_INET6 IPv6 : ํ”„๋กœํ† ์ฝœ ์ฒด๊ณ„ ์‚ฌ์šฉ

PF_UNIX : ์œ ๋‹‰์Šค ๋ฐฉ์‹์˜ ํ”„๋กœํ† ์ฝœ ์ฒด๊ณ„ ์‚ฌ์šฉ (ํ”„๋กœ์„ธ์Šค๊ฐ„ ํ†ต์‹ )

PF_NS XEROX : ๋„คํŠธ์›Œํฌ ์‹œ์Šคํ…œ์˜ ํ”„๋กœํ† ์ฝœ ์ฒด๊ณ„ ์‚ฌ์šฉ

PF๋Š” Protocol Family
PF๋Œ€์‹  AF๋ฅผ ์‚ฌ์šฉํ•ด๋„ ๋ฌด๋ฐฉ. (ex. PF_INET -> AF_INET)

1.1.2. type: ์„œ๋น„์Šค ํƒ€์ž…

โ€ป TCP/IP, UDP๋ž€?
SOCK_STREAM : ์ŠคํŠธ๋ฆผ ๋ฐฉ์‹์˜ ์†Œ์ผ“ ์ƒ์„ฑ (TCP/IP)

SOCK_DGRAM : ๋ฐ์ดํ„ฐ๊ทธ๋žจ ๋ฐฉ์‹์˜ ์†Œ์ผ“ ์ƒ์„ฑ (UDP)

SOCK_RAW : raw ๋ชจ๋“œ์˜ ์†Œ์ผ“ ์ƒ์„ฑ

1.1.3. protocol: ํ”„๋กœํ† ์ฝœ

IPPROTO_TCP : TCP ๊ธฐ๋ฐ˜. ๊ฐ’์€ 0์ด๋‹ค.

IPPROTO_UDP : UDP ๊ธฐ๋ฐ˜. ๊ฐ’์€ 0์ด๋‹ค.
// ์šฐ๋ฆฌ๊ฐ€ ์‚ฌ์šฉํ•˜๋Š” ํ”„๋กœํ† ์ฝœ์ธ TCP, UDP๊ฐ€ 0์ด๋ฏ€๋กœ 0์œผ๋กœ ์จ๋„ ๋ฌด๋ฐฉํ•˜๋‹ค.
// ๊ตฌ์ฒด์ ์ธ ํ”„๋กœํ† ์ฝœ์„ ์„ ํƒํ•  ๋•Œ ์‚ฌ์šฉํ•˜๋Š”๋ฐ ๋Œ€๋ถ€๋ถ„์˜ ์‘์šฉ ํ”„๋กœ๊ทธ๋ ˜์—์„œ๋Š” 0์œผ๋กœ ์ง€์ •ํ•˜๋ฉด ๋œ๋‹ค.


~cpp 
์˜ˆ์ œ)

main(){
int sockfd;

	sockfd = socket(AF_INET, SOCK_STREAM, 0);

	if(sockfd == -1)
		fprintf(stderr, "socket ํ•จ์ˆ˜์—์„œ ์—๋Ÿฌ"), exit(1);
	// ์—๋Ÿฌ๊ฐ€ ๋‚ฌ์„๊ฒฝ์šฐ( sockfd == -1) ์—๋Ÿฌ๋ฅผ ์ถœ๋ ฅํ•˜๊ณ  ํ”„๋กœ๊ทธ๋žจ ์ข…๋ฃŒ.
}

1.2. ๋„คํŠธ์›Œํฌ ์ •๋ณด

~cpp 
struct sockaddr {

    u_short sa_family;    /* address family */

    char sa_data[14];    /* ์ฃผ์†Œ(IP ์ฃผ์†Œ + ํฌํŠธ ๋ฒˆํ˜ธ) */

};


~cpp 
struct sockaddr_in {

short sin_family;			// ์ฃผ์†Œ ์ฒด๊ณ„๋ฅผ ๋‚˜ํƒ€๋‚ธ๋‹ค.

u_short sin_port;			// port ๋ฒˆํ˜ธ

struct in_addr sin_addr;		// ip ์ฃผ์†Œ

char sin_zero[8];			// ์“ฐ์ง€ ์•Š๋Š” ์ฃผ์†Œ

};

โ€ป ์™œ sockaddr๊ณผ sockaddr_in์˜ structure๊ฐ€ ๊ฐ™์„๊นŒ?

1.2.1. sin_family: // ์ฃผ์†Œ์ฒด๊ณ„

AF_INET : ์ธํ„ฐ๋„ท ์ฃผ์†Œ ์ฒด๊ณ„

AF_UNIX : ์œ ๋‹‰์Šค ํŒŒ์ผ ์ฃผ์†Œ ์ฒด๊ณ„

AF_NS XEROX : ์ฃผ์†Œ ์ฒด๊ณ„

// sockaddr_in ์€ TCP/IP์ฒด์ œ ์ด๋ฏ€๋กœ AF_INET๋งŒ ์‚ฌ์šฉํ•œ๋‹ค. -> TCP/IP๋Š” ์ธํ„ฐ๋„ท ๊ธฐ๋ฐ˜์ด๋ฏ€๋กœ.
// AF_INET/PF_INET -> ์ธํ„ฐ๋„ท ํ”„๋กœํ† ์ฝœ ์ฒด๊ณ„ ์‚ฌ์šฉ.


~cpp 
๋ฐ์ดํ„ฐ๋ฅผ Big-Endian์œผ๋กœ ๋ณ€ํ™˜ ์‹œ์ผœ์ฃผ๋Š” ์ฒด๊ณ„.

unsigned short integer ๋ณ€ํ™˜ (2๋ฐ”์ดํŠธ ํฌ๊ธฐ)
  htons(): host-to-network ๋ฐ”์ดํŠธ ๋ณ€ํ™˜ (Big-Endian์œผ๋กœ ๋ณ€ํ™˜)
  ntohs(): network-to-host ๋ฐ”์ดํŠธ ๋ณ€ํ™˜ (ํ•ด๋‹น ์‹œ์Šคํ…œ)

unsigned long integer ๋ณ€ํ™˜ (4๋ฐ”์ดํŠธ ํฌ๊ธฐ)
  htonl(): host-to-network ๋ฐ”์ดํŠธ ๋ณ€ํ™˜ (Big-Endian์œผ๋กœ ๋ณ€ํ™˜)
  ntohl(): network-to-host ๋ฐ”์ดํŠธ ๋ณ€ํ™˜ (ํ•ด๋‹น ์‹œ์Šคํ…œ)

 โ€ป ์™œ ์šฐ๋ฆฌ๋Š” ๋ฐ์ดํ„ฐ๋ฅผ Big-Endian์œผ๋กœ ๋ณ€ํ™˜ ์‹œ์ผœ์ฃผ์–ด์•ผํ• ๊นŒ?
 โ€ป ๊ทธ๋ ‡๋‹ค๋ฉด ์šฐ๋ฆฌ๊ฐ€ ์ „์†กํ•˜๋Š” ๋ฐ์ดํ„ฐ ๋ชจ๋‘ Big-Endian์œผ๋กœ ๋ณ€ํ™˜ ์‹œ์ผœ์ฃผ์–ด์•ผํ• ๊นŒ?

1.2.2. sin_port:

NULL : ์ž„์˜์˜ ํฌํŠธ๋ฅผ ํ• ๋‹นํ•œ๋‹ค. client์—์„œ ์‚ฌ์šฉํ•œ๋‹ค.
// u_short sin_port ์€ Big-Endian์„ ์‚ฌ์šฉํ•œ๋‹ค.
// ๋”ฐ๋ผ์„œ Little_Endian์„ ์‚ฌ์šฉํ•˜๋Š” ์‹œ์Šคํ…œ์—์„œ๋Š” Big-Endian์œผ๋กœ ๋ฐ”๊ฟ”์ค˜์•ผํ•œ๋‹ค.

1.2.3. sin_addr:

INADDR_ANY : ์ž๊ธฐ ์ž์‹ ์˜ ์ฃผ์†Œ๋ฅผ ํ• ๋‹นํ•œ๋‹ค. (== 0)
// sin_addr์€ ์ธํ„ฐ๋„ท ์ฃผ์†Œ๋ฅผ ๋‹ด๊ณ  ์žˆ์œผ๋ฏ€๋กœ 4 ๋ฐ”์ดํŠธ๊ฐ€ ํ•„์š”ํ•˜๋‹ค.
cf. ๋„๋ฉ”์ธ ๋„ค์ž„์„ ํ†ตํ•œ ์—ฐ๊ฒฐ์€ ์„ค๋ช…ํ•˜์ง€ ์•Š๊ฒ ์Šต๋‹ˆ๋‹ค.


~cpp 
struct in_addr {
	unsigned long s_addr;
};


~cpp 
/*
	inet_addr(): ์ฃผ์†Œ๋ฅผ longํ˜•์œผ๋กœ ๊ณ„์‚ฐํ•˜๊ณ  htonl()๋ฅผ ์‚ฌ์šฉํ•ด Big-Endian์œผ๋กœ ๋ณ€ํ™˜ ํ›„ ๊ฐ’์„ return ํ•œ๋‹ค.
		// 165.194.27.129 -> 165*256*256*256 + 194*256*256 + 27*256 + 129 = 2780961665
		// 2780961665 ์˜ ๊ฐ’์€ Little-Endian ์ฒด๊ณ„์—์„œ๋Š” 811BC2A5์ด๋‹ค.
		// ์ด๊ฒƒ์„ A5C21B81๋กœ ๋ฐ”๊ฟ” ์ €์žฅํ•œ๋‹ค.


์˜ˆ์ œ )
	ina.sin_addr.s_addr = inet_addr("127.0.0.1");
*/

1.2.4. sin_zero''''''8'''''':

// sin_zero ๋ฐฐ์—ด์€ ํ•ญ์ƒ 0์œผ๋กœ ์ฑ„์›Œ์ ธ ์žˆ์–ด์•ผํ•œ๋‹ค.

โ€ป ์™œ sin_zero๊ฐ€ ๋งŒ๋“ค์–ด์กŒ์„๊นŒ์š”?

~cpp 
์˜ˆ์ œ)

#define PORT 9999
#define SERVER_IP "165.194.27.129"

main(){
struct sockaddr_in ina;

	memset((struct sockaddr *)&ina, 0, sizeof(struct sockaddr));
	// sin_zero๋ฅผ 0์œผ๋กœ ์ฑ„์šด๋‹ค.
	// bzero๋ผ๋Š” ํ•จ์ˆ˜๋„ ์žˆ์ง€๋งŒ ์ดˆ๊ธฐ์— 0์œผ๋กœ ์ฑ„์šฐ๋Š” ๊ฒƒ์ด ํŽธํ•˜๋‹ค.
	// bzero(&(ina.sin_zero), 8);

	ina.sin_port = htons(PORT);			// PORT์˜ ๊ฒฝ์šฐ ์ •์ˆ˜๋ฅผ ๋„ฃ์–ด์•ผํ•œ๋‹ค.

	ina.sin_addr.s_addr = inet_addr(SERVER_IP);	// ํด๋ผ์ด์–ธํŠธ์˜ ๊ฒฝ์šฐ
							// SERVER_IP์˜ ๊ฒฝ์šฐ ๋ฌธ์ž์—ด ํฌ์ธํ„ฐ๋ฅผ ๋„ฃ์–ด์•ผํ•œ๋‹ค.
		// 165.194.27.129 -> 165*256*256*256 + 194*256*256 + 27*256 + 129 = 2780961665 ๋กœ ์ €์žฅ์ด ๋œ๋‹ค.
	// ina.sin_addr.s_addr = INADDR_ANY;		// ์„œ๋ฒ„์˜ ๊ฒฝ์šฐ
}

2. Server ๊ฐ€ ๋  ํ”„๋กœ๊ทธ๋žจ์— ํ•„์š”ํ•œ ํ•จ์ˆ˜



2.1. Bind - socket๊ณผ ๋„คํŠธ์›Œํฌ ์ •๋ณด๋ฅผ ์—ฐ๊ฒฐํ•˜๋Š” Bind!!!

~cpp 
#include <sys/socket.h>

int bind(int sockfd, struct sockaddr *myaddr, int addrlen);
// ์„ฑ๊ณต ์‹œ 0, ์‹คํŒจ ์‹œ -1 ๋ฆฌํ„ด


~cpp 
์˜ˆ์ œ)

	if( bind(sockfd, (struct sockaddr *)&ina, sizeof(struct sockaddr) == -1 )
		fprintf(stderr, "bind์—์„œ ์—๋Ÿฌ๊ฐ€ ๋‚ฌ์Šต๋‹ˆ๋‹ค.n")), exit(1);

2.2. listen - client์˜ ์š”์ฒญ์„ ๊ธฐ๋‹ค๋ฆฐ๋‹ค!

~cpp 
#include <sys/socket.h>

int listen(int sockfd, int backlog);
// ์„ฑ๊ณต ์‹œ 0, ์‹คํŒจ ์‹œ -1 ๋ฆฌํ„ด

// backlog๋Š” ์„œ๋ฒ„์— ์ ‘์†ํ•  ์‚ฌ๋žŒ์˜ ๋Œ€๊ธฐ์ž Maximum์„ ์˜๋ฏธํ•œ๋‹ค.


~cpp 
์˜ˆ์ œ)

#deinfe BACKLOG 5		// ๋Œ€๊ธฐ์ž๊ฐ€ 5๋ช…์ด ๋„˜์œผ๋ฉด ์ ‘์† ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค.

	if( listen(sockfd, BACKLOG) == -1 )
		fprintf(stderr, "listen์—์„œ ์—๋Ÿฌ๊ฐ€ ๋‚ฌ์Šต๋‹ˆ๋‹ค.n"), exit(1);

2.3. accpet - client์˜ ์š”์ฒญ์„ ๋ฐ›์•„๋“ค์ธ๋‹ค!

~cpp 
#include <sys/socket.h>

int accept(int sockfd, struct sockaddr *addr, int *addrlen);
// ์„ฑ๊ณต ์‹œ ํŒŒ์ผ ๋””์Šคํฌ๋ฆฝํ„ฐ, ์‹คํŒจ ์‹œ -1 ๋ฆฌํ„ด
// *addrlen์— ์ฃผ์˜. accept๋Š” client์˜ ์ธํ„ฐ๋„ท ์ •๋ณด๊ฐ€ ๋“ค์–ด์˜ค๋ฉด addrlen์˜ ํฌ๊ธฐ(struct sockaddr_in์˜ ํฌ๊ธฐ)์™€
// ๋น„๊ต๋ฅผ ํ•˜์—ฌ ํฌ๋‹ค๋ฉด ๋ฐ›์•„๋“ค์ด์ง€ ์•Š๊ณ , ์ž‘๋‹ค๋ฉด ํฌ๊ธฐ๋ฅผ ์ค„์ผ๊ฒƒ์ด๋‹ค.
// child process๋ฅผ ์ƒ์„ฑํ•ด ๋‹ค์ค‘ ์—ฐ๊ฒฐ์„ ํ•˜๋Š” ๊ฒƒ์€ ์„ค๋ช…ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.


~cpp 
์˜ˆ์ œ )

// int server_sock, client_sock
// struct sockaddr_in server_addr, client_sock

int sizeof_sockaddr_in;

	sizeof_sockaddr_in = sizeof(struct sockaddr_in);

	client_sock = accept(server_sock, (struct sockaddr *)&client_addr, &sizeof_sockaddr_in);

	if( client_sock == -1 )
		fprintf(stderr, "accept์—๋Ÿฌ. client๊ฐ€ ์„œ๋ฒ„์— ์ ‘์† ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.");

3. Client ๊ฐ€ ๋  ํ”„๋กœ๊ทธ๋žจ์— ํ•„์š”ํ•œ ํ•จ์ˆ˜



3.1. connect - Server์— ์—ฐ๊ฒฐํ•œ๋‹ค.

โ€ป connect์™€ server ํ•จ์ˆ˜์ค‘ ์–ด๋– ํ•œ ํ•จ์ˆ˜๊ฐ€ ๋‹ฎ์•˜๋Š”์ง€ ์ด์•ผ๊ธฐ ํ•ด๋ณด์ž.
โ€ป ์ด๋ฅผ ์ด์•ผ๊ธฐ ํ•ด๋ณด๊ณ  client์˜ ํ”„๋กœ๊ทธ๋žจ์˜ ๋„คํŠธ์›Œํฌ ์ •๋ณด(struct sockaddr_in)์—๋Š” ๋ฌด์—‡์ด ๋“ค์–ด๊ฐ€์•ผํ•˜๋Š”์ง€ ์ด์•ผ๊ธฐํ•ด๋ณด์ž.

~cpp 
#include <sys/types.h>
#include <sys/socket.h>

int connect(int sockfd, struct sockaddr *serv_addr, int addrlen);
// ์„ฑ๊ณต ์‹œ 0, ์‹คํŒจ ์‹œ -1 ๋ฆฌํ„ด


~cpp 
์˜ˆ์ œ )

	if( connect(client_sock, (struct sockaddr *)&client_addr, sizeof(struct sockaddr)) == -1 )
		fprintf(stderr, "์„œ๋ฒ„์— connect ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค."), exit(1);

4. ์ •๋ฆฌ์— ํ•„์š”ํ•œ ํ•จ์ˆ˜


4.1. close ํŒŒ์ผ์„ ๋‹ซ๋Š”๋‹ค.

~cpp 
#include <unistd.h>

int close(int fildes);

// ์„ฑ๊ณต ์‹œ 0, ์‹คํŒจ ์‹œ -1 ๋ฆฌํ„ด


~cpp 
์˜ˆ์ œ )

	close(sockfd);

5. server/client ๊ณตํ†ต - ์ž…์ถœ๋ ฅ ํ•จ์ˆ˜



5.1. send/write - ์ƒ๋Œ€์—๊ฒŒ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณด๋‚ธ๋‹ค.

~cpp 
#include <unistd.h>

ssize_t send(int fildes, const void * buf, size_t nbytes, unsigned int flags);
ssize_t write(int fildes, const void * buf, size_t nbytes);

// ์„ฑ๊ณต ์‹œ ์ „๋‹ฌ ํ•œ ๋ฐ”์ดํŠธ ์ˆ˜, ์‹คํŒจ ์‹œ -1 ๋ฆฌํ„ด


~cpp 
์˜ˆ์ œ )

char buf1[] = "Hello, World!";
char *buf2 = "Hello, World!";

	if( send(client_sock, buf1, sizeof(buf), 0) == -1 )
		fprintf(stderr, "send error");

	if( write(client_sock, buf2, strlen(buf2)) == -1 )
		fprintf(stderr, "write error");

// ํƒ€ ์‹œ์Šคํ…œ์œผ๋กœ ์ด์‹์„ ์œ„ํ•ด ๋˜๋„๋ก send๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.

5.2. recv/read - ์ƒ๋Œ€์—๊ฒŒ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›๋Š”๋‹ค.

~cpp 
#include <unistd.h>

ssize_t recv(int fildes, void *buf, size_t nbytes, unsigned int flags);
ssize_t read(int fildes, void *buf, size_t nbytes);

// ์„ฑ๊ณต ์‹œ ์ˆ˜์‹  ํ•œ ๋ฐ”์ดํŠธ ์ˆ˜(๋‹จ EOF๋งŒ๋‚˜๋ฉด 0), ์‹คํŒจ ์‹œ -1 ๋ฆฌํ„ด


~cpp 
์˜ˆ์ œ )

char buf1[200];
char buf2[200];
int str_len;

	str_len = recv(sockfd, buf1, sizeof(buf1), 0);
	str_len = read(sockfd, buf2, sizeof(buf2));

	buf1[str_len] = 0;			// ๋ฐฐ์—ด์˜ ๋์„ ์„ค์ •ํ•ด์ค€๋‹ค. ํ•˜์ง€ ์•Š์œผ๋ฉด ๋’ค์˜ ์“ฐ๋ ˆ๊ธฐ ๊ฐ’๊นŒ์ง€ ์ ‘๊ทผ๋œ๋‹ค.
	buf1[str_len] = 0;

// ํƒ€ ์‹œ์Šคํ…œ์œผ๋กœ ์ด์‹์„ ์œ„ํ•ด ๋˜๋„๋ก send๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.

6. โ€ป ์œˆ๋„์šฐ ๊ธฐ๋ฐ˜์—์„œ๋Š”...

~cpp 
โ—Ž Visual C++์—์„œ ๋นˆ ์†Œ์Šค ํŒŒ์ผ ํ•˜๋‚˜๋ฅผ ์—ฐ๋‹ค.
Project -> Setting -> LINK ๋ฉ”๋‰ด -> Object/library modules: ์˜ ๋๋ถ€๋ถ„์— ws2_32.lib ๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค.


โ—Ž #include <sys/socket.h>		->	#include <winsock2.h>

โ—Ž UNIX ์ฒด๊ณ„์—์„œ ์‚ฌ์šฉํ•˜๋˜ ํ•จ์ˆ˜๋“ค์˜ ํ—ค๋”ํŒŒ์ผ์ด Windows ๊ธฐ๋ฐ˜์—์„œ๋Š” ์กด์žฌํ•˜์ง€ ์•Š์„ ์ˆ˜๋„ ์žˆ๋‹ค.

โ—Ž struct sockaddr_in		->	SOCKADDR_IN

โ—Ž int sockfd;			->	SOCKET sockfd;
// ์†Œ์ผ“ ๋””์Šคํฌ๋ฆฝํ„ฐ			// ์†Œ์ผ“ ํ•ธ๋“ค


โ—Ž main() ํ•จ์ˆ˜ ๋‚ด๋ถ€์—

WSADATA wsaDATA;		// ์ถ”๊ฐ€. WSADATAํ˜•์˜ ๋ณ€์ˆ˜๋ฅผ ์„ ์–ธํ•œ๋‹ค.

if( WSAStartup(MAKEWORD(2,2), &wsaData) != 0)
	fprintf(stderr, "WSAStartup Error"), exit(1);
				// ์ถ”๊ฐ€. WSAStartup() ์€ socket์˜ ๋ฒ„์ ผ์„ ws2_32 ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ์ „๋‹ฌํ•œ๋‹ค.
// ํ”„๋กœ๊ทธ๋žจ์ด ๋๋‚  ๋•Œ, ํ•ญ์ƒ WSACleanup()์œผ๋กœ ๋ฆฌ์†Œ์Šค๋ฅผ ํ•ด์ œํ•ด์•ผํ•œ๋‹ค.


~cpp 
์˜ˆ์ œ)

#include <winsock2.h>

main(){
WSADATA wsaDATA;

SOCKET sockfd;
// UNIX ๊ธฐ๋ฐ˜์˜ int sockfd;
SOCKADDR_IN ina;
// UNIX ๊ธฐ๋ฐ˜์˜ struct sockaddr_in ina;

if( WSAStartup(MAKEWORD(2,2), &wsaData) != 0)
	fprintf(stderr, "WSAStartup Error"), exit(1);

... ๋‚ด์šฉ

WSACleanup();

}

7. server ์˜ˆ์ œ



~cpp 
#include <stdio.h>
#include <winsock2.h>

#define PORT 9999		// ์„œ๋ฒ„์˜ 9999๋ฒˆ ํฌํŠธ๋ฅผ ์—ฐ๋‹ค
#define BACKLOG 5

void error(char *buf)
{
	puts(buf), exit(1);
}

main(){
WSADATA wsaData;

SOCKET server_sock;		// ์„œ๋ฒ„์˜ socket์„ ์ƒ์„ฑ
SOCKET client_sock;		// ํด๋ผ์ด์–ธํŠธ์˜ socket์„ ์ƒ์„ฑ

SOCKADDR_IN server_addr;	// ๋„คํŠธ์›Œํฌ์˜ ์ •๋ณด๋ฅผ ๋‹ด์„ structure ์ƒ์„ฑ.
SOCKADDR_IN client_addr;

int sizeof_sockaddr_in;
char msg[] = "Hello, World!";

	if( WSAStartup(MAKEWORD(2,2), &wsaData) == -1 )
		error("WSAStartup Error");


// socket ์„ค์ •
// ํ”„๋กœ๊ทธ๋ž˜๋จธ๋Š” ์ด๊ฒƒ์„ ํ†ตํ•ด ๋„คํŠธ์›Œํฌ์™€ ๋Œ€ํ™”๋ฅผ ํ•œ๋‹ค.

	server_sock = socket(AF_INET, SOCK_STREAM, 0);
	if( server_sock == -1 )
		error("server socket error");


// ๋„คํŠธ์› ์ •๋ณด ์„ค์ •
// ์ด๊ฒƒ์€ ํ”„๋กœ๊ทธ๋žจ์ด socket๊ณผ ์—ฐ๊ฒฐํ•  ์ •๋ณด๋ฅผ ๋‹ด๊ณ ์žˆ๋‹ค.

	memset((SOCKADDR_IN *)&server_addr, 0, sizeof(SOCKADDR_IN));
	// struct sockaddr_in	->	SOCKADDR_IN
	server_addr.sin_family = AF_INET;
	server_addr.sin_addr.s_addr = INADDR_ANY;	// ์ž์‹ ์˜ ์ฃผ์†Œ๋กœ ์„ค์ •ํ•œ๋‹ค.
	server_addr.sin_port = htons(PORT);


// socket๊ณผ ๋„คํŠธ์› ์ •๋ณด๋ฅผ bind()๋กœ ์—ฐ๊ฒฐํ•œ๋‹ค.

	if( bind(server_sock, (sockaddr *)&server_addr, sizeof(SOCKADDR_IN)) == -1 )
		error("bind() ์—๋Ÿฌ");


// ์ค€๋น„๋Š” ๋๋‚ฌ๋‹ค!
// listen()์œผ๋กœ client์˜ ์—ฐ๊ฒฐ ์š”์ฒญ์„ ๊ธฐ๋‹ค๋ฆฌ์ž.
// client์˜ ์š”์ฒญ์ด ์˜ฌ ๋•Œ ๊นŒ์ง€ ์„œ๋ฒ„๋Š” ์—ฌ๊ธฐ์„œ ๊ธฐ๋‹ค๋ฆฐ๋‹ค.

	if( listen(server_sock, BACKLOG) == -1 )
		error("listen() ์—๋Ÿฌ");


// client์˜ ์š”์ฒญ์ด ์˜ค๋ฉด server๋Š” accept() ํ•จ์ˆ˜๋กœ ์š”์ฒญ์„ ๋ฐ›์•„๋“ค์ธ๋‹ค.
// client์™€์˜ ๋ฐ์ดํ„ฐ ์ „์†ก์„ ์œ„ํ•ด client ์†Œ์ผ“ ๋””์Šคํฌ๋ฆฝํ„ฐ๊ฐ€ ํ•„์š”ํ•˜๋‹ค.

	sizeof_sockaddr_in = sizeof(SOCKADDR_IN);

	while(1)
	{
		client_sock = accept(server_sock, (sockaddr *)&client_addr, &sizeof_sockaddr_in);
		if( client_sock == -1 )
		{
			// accept๊ฐ€ ์‹คํŒจํ•˜๋ฉด while์˜ ์ฒ˜์Œ์œผ๋กœ ๋Œ์•„๊ฐ€ ๋‹ค์‹œ client๋ฅผ ๊ธฐ๋‹ค๋ฆฐ๋‹ค.
			fprintf(stderr, "accept() ์—๋Ÿฌ");
			continue;
		}

		send(client_sock, msg, sizeof(msg), 0);

		//close(client_sock);
		WSACleanup();
	}


	exit(0);
	// exit๋กœ ์ข…๋ฃŒ๋ฅผ ํ•˜๋ฉด ๋ชจ๋“  ํŒŒ์ผ ๋””์Šคํฌ๋ฆฝํ„ฐ๋ฅผ ์ž๋™์œผ๋กœ ๋‹ซ๊ณ  ์ข…๋ฃŒํ•œ๋‹ค.
}

โ€ป ์ปดํ“จํ„ฐ๋Š” ํ•˜๋‚˜์˜ ์ฒ˜๋ฆฌ๋ฐ–์— ํ•˜์ง€ ๋ชปํ•œ๋‹ค. ๋”ฐ๋ผ์„œ ์œ„์˜ ์†Œ์Šค๋Š” ํ•˜๋‚˜์˜ client๋ฐ–์— ๋ฐ›์•„ ๋“ค์ผ ์ˆ˜ ๋ฐ–์— ์—†๋‹ค.
์–ด๋–ป๊ฒŒ ํ•˜๋ฉด ์—ฌ๋Ÿฌ client๋ฅผ ๋™์‹œ์— ๋ฐ›์•„๋“ค์ผ ์ˆ˜ ์žˆ์„๊นŒ?

8. ์‹ค์Šต

์œ„์˜ server ์— ์ ‘์† ํ•˜๋Š” client ํ”„๋กœ๊ทธ๋žจ์„ ์งœ๊ณ , Server๊ฐ€ ๋ณด๋‚ด๋Š” ๋ฉ”์„ธ์ง€์ธ "Hello, World!"๋ž€ ๋ฌธ์žฅ์„ clinet ํ™”๋ฉด์— ์ถœ๋ ฅํ•˜๋„๋ก ํ•œ๋‹ค.

9. ์ฐธ๊ณ  ์‚ฌ์ดํŠธ

An Introduction to Socket Programming : http://www.uwo.ca/its/doc/courses/notes/socket/

Beej's Guide to Network Programming : http://www.ecst.csuchico.edu/~beej/guide/net/html/

Beej's ๋ฒˆ์—ญํŒ : ์„œ์น˜์—”์ง„์—์„œ ์ฐพ์•„๋ณด์„ธ์š”. (๋ฌด์ฑ…์ž„)

Socket Programming in Python : http://www.amk.ca/python/howto/sockets/

IPv6 Socket Programming : http://www.joinc.co.kr/modules/moniwiki/wiki.php/article_IPv6_Programing?action=print2

----
ํ”„๋กœ๊ทธ๋ž˜๋ฐ๋ถ„๋ฅ˜
Valid XHTML 1.0! Valid CSS! powered by MoniWiki
last modified 2021-02-07 05:28:20
Processing time 0.0230 sec