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.0350 sec