[Network] Network Commands | Socket Programming

pos++·2024년 5월 26일

Network

목록 보기
2/3
post-thumbnail

2023.11.20 TIL

Network Commands

telnet

Remote computer에 login, 명령을 실행할 수 있는 text 기반 network protocol
기본적인 TCP 연결 생성용
(요즘은 잘 안쓴다)

nc

Network connection, I/O를 다루는 utility program(command line tool)
TCP/UDP protocol을 사용하여 socket을 열고 data 송수신, client-server 연결 설정

Network connection

  • TCP: nc [options] [hostname/IP] [port#]
  • UDP: nc -u [options] [hostname/IP] [port#]

File transfer

  • Receiver: nc -l [port#] > [filename] → port로 listen(TCP 연결 기다림), redirection
  • Sender: nc [hostname/IP] [port#] < [filename] → TCP 열결을 만들고 file 내용 입력받음
  • Ex)
    • Receiver: nc -l 10000 > b.txt → 10000까지만 치면 nc가 TCP server로 동작하겠다는 것, 화면에 내용 출력 → 여기서는 b.txt로 받겠다
    • Sender: nc localhost 10000 < a.txt → 원래 10000까지만 치고 Enter → 입력한 값이 그대로 전송됨. 여기서는 a.txt를 입력으로, ^D
    • Receiver: ^D, b.txt가 만들어짐, a.txt도 전송되는
  • 미쳤다…

Port scan

  • nc -zv [hostname/IP] [port-range]
    • -zv : Port scan mode 설정
    • -z : Just scan for listening daemons, without sending any data to them
    • -v : 상세 정보 출력
  • Ex: nc -zv www.programmers.co.kr 80-90

ifconfig

Network interface 설정 확인/변경

ping

Network connection 상태 확인

  • ping [hostname/IP] : 해당 host로 ICMP packet을 보내 도달 여부 확인
  • ping [hostname/IP] -c [packet count] : 지정된 packet수만큼 ICMP packet 보내고 응답 기다림
  • ping [hostname/IP] -l [interval] : ICMP packet을 보내는 간격 지정
  • ping [hostname/IP] -s [packet size] : ICMP packet의 크기 지정

traceroute

Destination까지 packet이 어떤 경로를 통해 전송되는지 추적

  • traceroute [hostname/IP] : 해당 host로 ICMP packet을 보내 경로를 추적
  • traceroute [hostname/IP] -m [max hop count] : 최대 hop수 지정
  • traceroute [hostname/IP] -p [dest port#] : Destination port에 도달하는데 사용될 port 지정

TTL expired → ttl이 0이 되었다는 error message
Port unavailable → Destination에서 보내는 error message

netstat

Network connection 상태 및 Active port 확인

  • netstat → 현재 활성화된 network connection 정보 출력
  • netstat -a → 모든 network connection 정보 출력
  • netstat -t → TCP network connection 정보 출력
  • netstat -u → UDP network connection 정보 출력

dig

  • dig [domain name] → 지정된 domain의 DNS 정보 조회
  • dig [domain name] +short → 짧은 형태로 조회결과 출력
  • dig [domain name] +trace → 조회한 DNS 정보의 경로 추적

ssh

Remote server에 안전하게 login, file 전송

scp

ssh protocol을 사용하여 local과 remote system간 file copy

curl

URL을 이용하여 Web page/File 등 data를 전송하거나 download

  • curl https://www.example.com → Web page download
  • curl -X POST -H "Content-Type: application/json" -d '{"username": "sanghwan", "password": "11111111"}' https://example.com/api/users → HTTP Header에 추가, Server로 data 전송

tcpdump

Network packet capture, 분석

  • tcpdump → 내 machine에 들어오고 나가는 packet들을 capture
  • tcpdump -i enp0s8 → interface 지정
  • tcpdump -c 10 → packet 10개만 capture
  • tcpdump host [IP] → 특정 IP에서 전송되는 모든 packet capture
  • tcpdump host port [port#] → 특정 port에서 발생하는 packet capture
  • tcpdump [protocol] → 특정 protocol을 사용하는 packet capture

Socket Programming

Host의 program - 여러개의 host에서 돌면 network application

Client-Server 방식

Client가 request, server가 response
Server는 항상 실행중이어야 함

P2P 방식

Peer 끼리 data를 주고받음
File 교환 등
상대 peer가 꺼져있거나, application이 실행중이지 않을 수 있다

Socket

Computer간 통신을 가능하게 하는 endpoint (Application의 process)
Socket을 사용하여 server와 client간 data 전송
Network application을 만든다는 것은 socket을 생성하고 socket을 사용해 data를 보낼 수 있게 하는 것

  • Stream Socket
    • TCP 기반 (Connection-oriented, Reliable)
    • Web browsing, Email
  • Datagram Socket
    • UDP 기반 (Connectionless, Unreliable)
    • Video streaming, Online game

TCP Server

server.c

#include <stdio.h>
#include <stdlib.h> 
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>

int main(int argc, char *argv[]) {
	struct sockaddr_in server, remote;  // 서버 주소, 상대방의 주소
	int request_sock, new_sock;  // 처음에 연결을 받아들이는 socket, 연결 요청이 들어올때마다 만드는 새로운 socket
	int bytesread, addrlen;
	int i;
	char buf[BUFSIZ];
	
	if (argc != 2) {
		(void) fprintf(stderr,"usage: %s port\n", argv[0]);
		exit(1);
	}
	if ((request_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {  // Internet을 사용, Stream Socket으로 생성
		perror("socket");
		exit(1);
	}

	memset((void *) &server, 0, sizeof (server));
	server.sin_family = AF_INET;
	server.sin_addr.s_addr = INADDR_ANY;  // 어느 주소로 request가 들어오든 처리할 수 있어야 하니까~
	server.sin_port = htons((u_short)atoi(argv[1]));  // 이 server가 몇번 port로 기다릴 것인가, host to network short(host type을 network type로)!!
	if (bind(request_sock, (struct sockaddr *)&server, sizeof (server)) < 0) {  // socket descriptor 지정, socket과 address(&server) matching해줌
		perror("bind");
		exit(1);
	}
	if (listen(request_sock, SOMAXCONN) < 0) {  // connection request를 queue에 저장하는데, 그 queue size를 지정
		perror("listen");
		exit(1);
	}

	for (;;) {
		addrlen = sizeof(remote);
		new_sock = accept(request_sock, (struct sockaddr *)&remote, &addrlen);  // request_sock로 들어오는 connection request를 accept, remote의 address를 저장하는 구조체의 주소(sockaddr 포인터로 casting)
		if (new_sock < 0) {
			perror("accept");
			exit(1);
		}
		printf("connection from host %s, port %d, socket %d\n", inet_ntoa(remote.sin_addr), ntohs(remote.sin_port), new_sock);
		
		for (;;) {
			bytesread = read(new_sock, buf, sizeof (buf) - 1);  // connected socket에서 read, 내용은 buf에, '\0' 자리를 남겨두기 위해 -1
			if (bytesread <= 0) {
				close(new_sock);
				break;
			}
			buf[bytesread] = '\0';  // read로 읽은 부분까지를 string으로 만들기
			printf("%s: %d bytes from %d: %s\n", argv[0], bytesread, new_sock, buf);
			for(i = 0; i < bytesread; i++)
				buf[i] = toupper(buf[i]);
			if (write(new_sock, buf, bytesread) != bytesread)  // connected socket에 읽은 내용 write
				perror("echo");
		}
	}

}
  • socket#는 file#와 같은 개념이다. (3~)
  • socket을 처음 생성하면 3번이다.
  • gcc -o srv server.c → server program compile
    • client는 nctelnet 사용
    • (다른 창에서) nc localhost 10000

Socket 관련 구조체

struct sockaddr {  // socket의 address를 의미
	__SOCKADDR_COMMON(sa_);  // socket address family -> u_short sa_family; 가 나옴
	char sa_data[14];  // 실제 data 저장하는곳, 14byte
};
#include <netinet/in.h>
struct sockaddr_in {
	short sin_family; // e.g. AF_INET
	
	// 14byte의 sa_data가 이 셋으로 쪼개짐
	unsigned short sin_port; // e.g. htons(3490), 2byte
	struct in_addr sin_addr; // see struct in_addr, below, 4byte
	char sin_zero[8]; // zero this if you want to(padding), 8byte
};

struct in_addr {
	unsigned long s_addr; // load with inet_aton(), 4byte
};
  • getsockopt(), setsockopt()
  • bind() → bind a name to socket
  • listen() → listen for connections on a socket
  • accept(), accept4() → accept a connection on a socket
  • inet_aton, inet_addr, inet_network, inet_ntoa, inet_makeaddr, inet_lnaof, inet_netof → Internet address manipulation routines
  • inet_pton → convert IPv4 and IPv6 addresses from text to binary form
  • htonl, htons, ntohl, ntohs → convert values between host and network byte order
  • gethostbyname, gethostbyaddr, sethostent, gethostent, endhostent, h_errno, herror, hstrerror, gethostbyaddr_r, gethostbyname2, gethostbyname2_r, gethostbyname_r, gethostent_r → get network host entry

Python Code

tcpsrv.py

from socket import *

serverPort = 12000
serverSocket = socket(AF_INET,SOCK_STREAM) 
serverSocket.bind((‘’,serverPort)) 
serverSocket.listen(1)
print ‘The server is ready to receive’
while True:
	connectionSocket, addr = serverSocket.accept() 
	sentence = connectionSocket.recv(1024).decode() 
	capitalizedSentence = sentence.upper() 
	connectionSocket.send(capitalizedSentence.encode()) 
	connectionSocket.close()
  • (server) python3 tcpsrv.py
  • (client) nc -l 12000

TCP Client

client.c

#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <string.h>
#include <unistd.h>

int main(int argc, char *argv[]) {
	struct hostent *hostp;  // host 정보 담음
	struct sockaddr_in server;  // server 주소 담음
	int sock;  // socket fd 담음
	char buf[BUFSIZ];
	int bytesread;

	if(argc != 3) {
		(void) fprintf(stderr,"usage: %s host port\n", argv[0]);
		exit(1); 
	}
	if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {  // socket descriptor 생성, Internet을 사용, Stream Socket으로 생성
		perror("socket");
		exit(1); 
	}

	if ((hostp = gethostbyname(argv[1])) == 0) {  // host IP 주소 get
		fprintf(stderr,"%s: unknown host\n",argv[2]); 
		exit(1);
	}
	memset((void *) &server, 0, sizeof (server));  // &server 주소부터 server 크기만큼 0으로 set
	server.sin_family = AF_INET;
	memcpy((void *) &server.sin_addr, hostp->h_addr, hostp->h_length);  // hostp의 값을 &server.sin_addr로 copy
	server.sin_port = htons((u_short)atoi(argv[2]));  // port#을 host to network short

	if (connect(sock, (struct sockaddr *)&server, sizeof (server)) < 0) {  // socket을 통해서 server machine에 TCP 연결을 해달라
		(void) close(sock);
		fprintf(stderr, "connect");
		exit(1); 
	}

	for (;;) {
		/* data from keyboard */
		if (!fgets(buf, sizeof buf, stdin)) {  // keyborad input, buf size 만큼만 받을 수 있다
			exit(0);
		}
		if (write(sock, buf, strlen(buf)) < 0) {  // socket descriptor에 write, client가 send
			perror("write");
			exit(1); 
		}
		bytesread = read(sock, buf, sizeof (buf) - 1);  // server에서 read, '\0' 자리를 남겨두기 위해 -1
		buf[bytesread] = '\0';
		printf("%s: got %d bytes: %s\n", argv[0], bytesread, buf); 
	}
}
  • gcc -o srv server.c
  • gcc -o cli client.c
  • (server) nc -l 10000 → waiting for TCP port 10000
  • (client) ./cli localhost 10000

Python Code

udpsrv.py

from socket import *

serverPort = 12000
serverSocket = socket(AF_INET, SOCK_DGRAM) 
serverSocket.bind(('', serverPort))
print (“The server is ready to receive”)
while True:
	message, clientAddress = serverSocket.recvfrom(2048)  # 만든 socket serverSocket으로 receive
	modifiedMessage = message.decode().upper() 
	serverSocket.sendto(modifiedMessage.encode(), clientAddress)  # clientAddress로 response 보냄
  • (server) python3 udpsrv.py
  • (client) nc -u localhost 12000

UDP Server

udpserver.c

#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <string.h>
#include <unistd.h>

int main(int argc, char *argv[]) {
	int sockid, nread, addrlen;
	struct sockaddr_in my_addr, client_addr; 
	char msg[50];
	if(argc != 2) {
		printf("%s myportid\n", argv[0]);
		return 0; 
	}
	printf("Server: creating socket\n");
	if ( (sockid = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {  // socket fd, UDP socket 생성
		printf("Server: socket error: %d\n",errno); 
		exit(0); 
	}

	printf("Server: binding my local socket\n");

	memset((char *) &my_addr, 0, sizeof(my_addr));  // address 만들기
	my_addr.sin_family = AF_INET;
	my_addr.sin_addr.s_addr = htonl(INADDR_ANY);  // 아무 address
	my_addr.sin_port = htons(atoi(argv[1]));  // host to network short

	if ( (bind(sockid, (struct sockaddr *) &my_addr, sizeof(my_addr)) < 0) ) {   // my_addr를 생성한 socket과 bind
		printf("Server: bind fail: %d\n",errno); 
		exit(0); 
	}

	printf("Server: starting blocking message read\n");
	nread = recvfrom(sockid,msg,sizeof(msg) - 1, 0, (struct sockaddr *) &client_addr, ((socklen_t *)&addrlen);  // read data from client, clinet_addr에는 message를 보낸 곳(client)의 주소가 저장되어 return
	msg[nread] = '\0';
	printf("Server: retrun code from read is %d\n",nread); 
	if (nread >0) 
		printf("Server: message is: %s\n",msg);

	close(sockid); 
}

Python Code

udpsrv.py

from socket import *

serverName = ‘hostname’
serverPort = 12000
clientSocket = socket(AF_INET, SOCK_DGRAM)
message = raw_input(’Input lowercase sentence:) 
clientSocket.sendto(message.encode(), (serverName, serverPort))  # encode해서 serverName으로 send
modifiedMessage, serverAddress = clientSocket.recvfrom(2048)  # server한테 받은 response
print modifiedMessage.decode()
clientSocket.close()
  • (server) nc -l 12000 -u
  • (client) python3 udpcli.py

Socket 관련 구조체

  • recv, recvfrom, recvmsg → receive a message from a socket
#include <sys/types.h>
#include <sys/socket.h>
ssize_t recv(int sockfd, void *buf, size_t len, int flags);  // TCP, flag 설정 가능

ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen);
ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags);  // 여러가지 parameter를 msghdr structure에 모아놓는다
  • (client) nc -u localhost 100000
  • (server) gcc -o udcsrc udpserver.c

UDP Client

udpcli.c

#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <string.h>
#include <unistd.h>

int main(int argc, char *argv[]) {
	int sockid, retcode;
	struct sockaddr_in my_addr, server_addr;  // client 주소, server 주소
	char msg[128];
	if(argc != 4) {
		printf("%s myport serveraddr serverport\n", argv[0]);
		return 0; 
	}
	printf("Client: creating socket\n");
	if ( (sockid = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {  // UDP socket 생성, 
		printf("Client: socket failed: %d\n",errno); 
		exit(0); 
	}

	printf("Client: binding my local socket\n");

	memset((char *) &my_addr, 0, sizeof(my_addr)); 
	my_addr.sin_family = AF_INET; 
	my_addr.sin_addr.s_addr = htonl(INADDR_ANY);  
	my_addr.sin_port = htons(atoi(argv[1]));  // 자신의 port#

	if ( (bind(sockid, (struct sockaddr *) &my_addr, sizeof(my_addr)) < 0) ) {  // UDP socket과 자기 주소, port# binding
		printf("Client: bind fail: %d\n",errno); 
		exit(0); 
	}

	printf("Client: creating addr structure for server\n"); 
	bzero((char *) &server_addr, sizeof(server_addr));  // 0으로 초기화
	server_addr.sin_family = AF_INET; 
	server_addr.sin_addr.s_addr = inet_addr(argv[2]);  // 숫자로 된 문자열(char *)를 address로 바꿔준다
	server_addr.sin_port = htons(atoi(argv[3]));  // host to network short

	printf("Client: initializing message and sending\n");
	sprintf(msg, "Hello world");
	retcode = sendto(sockid,msg,strlen(msg),0,(struct sockaddr *) &server_addr, sizeof(server_addr));  // send UDP packet to server_addr, data: Hello World
}

Error Solved

  1. struct “hostent” has no field “h_addr”
    #define h_addr h_addr_list[0]을 해주면 된다고 한다.
  2. Identifier “u_short” is undefined
    u_short는 standard가 아니라고 한다. 대한 unsigned short를 사용하니 에러가 사라졌다.

Socket 관련 함수들

  • send(), sendto(), sendmsg() → send a message on a socket
#include <sys/types.h>
#include <sys/socket.h>

ssize_t send(int sockfd, const void *buf, size_t len, int flags);  // TCP

ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen);
ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags);
  • (client) gcc -o udpcli.c
  • (client) ./udpcli 20000 10.0.2.15 10000
  • (server) nc -l 10000 -u

Server, Client 동시에 사용

  • (server) ./udpsrv 10000
  • (client) ./udpcli 20000 localhost 10000

Python Code

udpcli.py

from socket import *

serverName = ‘hostname’
serverPort = 12000
clientSocket = socket(AF_INET, SOCK_DGRAM)
message = raw_input(’Input lowercase sentence:) 
clientSocket.sendto(message.encode(), (serverName, serverPort))  # encode해서 serverName으로 send
modifiedMessage, serverAddress = clientSocket.recvfrom(2048)  # server한테 받은 response
print modifiedMessage.decode()
clientSocket.close()
  • (server) python3 udpsrv.py
  • (client) python3 udpcli.py

Multiplexing File Descriptors

  • select()
    • I/O Multiplexing, 여러개의 fd를 감시
    • 어떤 descriptor가 read/write 가능한 상태인지 확인하여 해당 descriptor 선택
    • 단일 process가 여러개의 I/O request 동시에 처리
    • select()가 호출되면 blocked, fd가 선택되면 return
    • return 이후, 선택된 fd에 대해 처리를 수행
    • #include <sys/select/h>
      fd_set mask;
      FD_SET(n, &mask)  // 3번 fd를 mask에 setting

serverorg.c

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>

int main(int argc, char *argv[])
{
	struct sockaddr_in server, remote;
	int request_sock, new_sock;  // server, client
	int i, nfound, fd, maxfd, bytesread, addrlen;
	fd_set rmask, mask;
	static struct timeval timeout = {5, 0}; /* 5 seconds */

	char buf[BUFSIZ];
	if (argc != 2)
	{
		(void)fprintf(stderr, "usage: %s port\n", argv[0]);
		exit(1);
	}
	if ((request_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)  // connection request 받는 port
	{
		perror("socket");
		exit(1);
	}

	memset((void *)&server, 0, sizeof server);
	server.sin_family = AF_INET;
	server.sin_addr.s_addr = INADDR_ANY;
	server.sin_port = htons((u_short)atoi(argv[1]));  // port# argument에서~
	if (bind(request_sock, (struct sockaddr *)&server, sizeof server) < 0)
	{
		perror("bind");
		exit(1);
	}
	if (listen(request_sock, SOMAXCONN) < 0)
	{
		perror("listen");
		exit(1);
	}

	FD_ZERO(&mask);
	FD_SET(request_sock, &mask);
	maxfd = request_sock;  // 3. 0~2는 이미 할당되어 있는 fd
	for (;;)
	{
		rmask = mask;  // select를 하면 return값에 의해 바뀌기 때문에 rmask로 copy를 해서 사용해야 한다
		nfound = select(maxfd + 1, &rmask, (fd_set *)0, (fd_set *)0, &timeout);  // read만 하고 write, exec은 안한다.
		if (nfound < 0)
		{
			if (errno == EINTR)
			{
				printf("interrupted system call\n");
				continue;
			}
			/* something is very wrong! */
			perror("select");
			exit(1);
		}
		if (FD_ISSET(request_sock, &rmask))  // request_sock에 입력이 들어온게 있다면
		{
			/* a new connection is available on the connetion socket */
			addrlen = sizeof(remote);
			new_sock = accept(request_sock, (struct sockaddr *)&remote, (socklen_t *)&addrlen);  // accept connection request
			if (new_sock < 0)
			{
				perror("accept");
				exit(1);
			}
			printf("connection from host %s, port %d, socket %d\n",
				   inet_ntoa(remote.sin_addr), ntohs(remote.sin_port),
				   new_sock);
			FD_SET(new_sock, &mask);
			if (new_sock > maxfd)
				maxfd = new_sock;  // connection request가 들어올 때마다 socket이 하나씩 늘어남
			FD_CLR(request_sock, &rmask);
		}
		for (fd = 4; fd <= maxfd; fd++)  // 4번 fd 이후는 모두 client와 연결된 socket이니까~
		{
			/* look for other sockets that have data available */
			if (FD_ISSET(fd, &rmask))
			{
				/* process the data */
				bytesread = read(fd, buf, sizeof(buf) - 1);
				if (bytesread < 0)
				{
					perror("read");
					/* fall through */
				}
				if (bytesread <= 0)
				{
					printf("server: end of file on %d\n", fd);
					FD_CLR(fd, &mask);
					if (close(fd))
						perror("close");
					continue;
				}
				buf[bytesread] = '\0';
				printf("%s: %d bytes from %d: %s\n",
					   argv[0], bytesread, fd, buf);
				for (i = 0; i < bytesread; i++)
					buf[i] = toupper(buf[i]);

				/* echo it back */
				if (write(fd, buf, bytesread) != bytesread)
					perror("echo");
			}
		}
	}
} /* main - serverorg.c */

clientorg.c

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <errno.h>
#include <netdb.h>
#include <string.h>
#include <ctype.h>

int main(int argc, char *argv[])
{
	struct hostent *hostp;
	struct sockaddr_in server;
	int sock;
	static struct timeval timeout = {5, 0}; /* five seconds */
	fd_set rmask, xmask, mask;
	char buf[BUFSIZ];
	int nfound, bytesread;
	if (argc != 3)
	{
		(void)fprintf(stderr, "usage: %s host port\n", argv[0]);
		exit(1);
	}
	if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
	{
		perror("socket");
		exit(1);
	}

	if ((hostp = gethostbyname(argv[1])) == 0)
	{
		fprintf(stderr, "%s: unknown host\n", argv[1]);
		exit(1);
	}
	memset((void *)&server, 0, sizeof server);
	server.sin_family = AF_INET;
	memcpy((void *)&server.sin_addr, hostp->h_addr, hostp->h_length);
	server.sin_port = htons((unsigned short)atoi(argv[2]));
	if (connect(sock, (struct sockaddr *)&server, sizeof(server)) < 0)
	{
		(void)close(sock);
		perror("connect");
		exit(1);
	}

	FD_ZERO(&mask);
	FD_SET(sock, &mask);
	FD_SET(fileno(stdin), &mask);
	for (;;)
	{
		rmask = mask;
		nfound = select(FD_SETSIZE, &rmask, (fd_set *)0, (fd_set *)0, &timeout);
		if (nfound < 0)
		{
			/* something is very wrong! */
			perror("select");
			exit(1);
		}
		if (FD_ISSET(fileno(stdin), &rmask))
		{
			/* data from keyboard */
			if (!fgets(buf, sizeof(buf) - 1, stdin))
			{
				if (ferror(stdin))
				{
					perror("stdin");
					exit(1);
				}
				exit(0);
			}
			if (write(sock, buf, strlen(buf)) < 0)
			{
				perror("write");
				exit(1);
			}
		}
		if (FD_ISSET(sock, &rmask))
		{
			/* data from network */
			bytesread = read(sock, buf, sizeof(buf) - 1);
			if (bytesread == 0)
			{
				perror("close connection");
				exit(1);
			}
			buf[bytesread] = '\0';
			printf("%s: got %d bytes: %s\n", argv[0], bytesread, buf);
		}
	}
} /* main - clientorg.c */
  • timeout → incomplete type is not allowed C/C++(70)
  • fd_set → identifier "fd_set" is undefined C/C++(20)
  • hostp→h_addr → struct "hostent" has no field "h_addr” C/C++(136)
  • select() → identifier "FD_SETSIZE" is undefined C/C++(20)

근데 compile, 실행은 잘 된다.


Socket 관련 함수 - 주소 관련 함수 예제

int inet_aton(const char *cp, struct in_addr *inp); • in_addr_t inet_addr(const char *cp);

in_addr_t inet_network(const char *cp);

char *inet_ntoa(struct in_addr in);

struct in_addr inet_makeaddr(in_addr_t net, in_addr_t host); • in_addr_t inet_lnaof(struct in_addr in);

in_addr_t inet_netof(struct in_addr in);

int inet_pton(int af, const char *src, void *dst);

Socket 관련 함수 - Socket option 관련 함수 예제

int getsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen);

int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen);

optname → socket level인지 특정 protocol에 대한 설정인지 지정하는 값

  • SOL_SOCKET : socket API level
  • IPPROTO_IP : IP protocol level
  • IPPROTO_TCP : TCP protocol level
profile
밀린 TIL 업로드 조금씩 정리중...

0개의 댓글