network programming week #1 j.p. yoo [email protected]

44
Network Programming Week #1 J.P. Yoo [email protected]

Upload: samantha-thomas

Post on 26-Mar-2015

222 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Network Programming Week #1 J.P. Yoo willow@konkuk.ac.kr

Network Programming Week #1

J.P. [email protected]

Page 2: Network Programming Week #1 J.P. Yoo willow@konkuk.ac.kr

TCP/IP Sockets in C: Practical Guide for

Programmers

Michael J. DonahooKenneth L. Calvert

Page 3: Network Programming Week #1 J.P. Yoo willow@konkuk.ac.kr

Network API

• Interface between application and protocol software.

ApplicationApplication

Network APINetwork API

Protocol AProtocol A Protocol BProtocol B Protocol CProtocol C

Page 4: Network Programming Week #1 J.P. Yoo willow@konkuk.ac.kr

Socket

• Programming Interface between application and network

• Network API sets for TCP/IP protocol suite

• A socket is an abstract representation of a communication endpoint.

• Sockets work with Unix I/O services just like files, pipes & FIFOs.– Difference

• establishing a connection• specifying communication endpoint addresses

Page 5: Network Programming Week #1 J.P. Yoo willow@konkuk.ac.kr

Unix Descriptor Table

Descriptor TableDescriptor Table

0

1

2

3

4

Data structure for file 0Data structure for file 0

Data structure for file 1Data structure for file 1

Data structure for file 2Data structure for file 2

Page 6: Network Programming Week #1 J.P. Yoo willow@konkuk.ac.kr

Socket Descriptor Structure

Descriptor TableDescriptor Table

0

1

2

3

4

Family: PF_INETFamily: PF_INETService: SOCK_STREAMService: SOCK_STREAMLocal IP: 111.22.3.4Local IP: 111.22.3.4Remote IP: 123.45.6.78Remote IP: 123.45.6.78Local Port: 2249Local Port: 2249Remote Port: 3726Remote Port: 3726

Family: PF_INETFamily: PF_INETService: SOCK_STREAMService: SOCK_STREAMLocal IP: 111.22.3.4Local IP: 111.22.3.4Remote IP: 123.45.6.78Remote IP: 123.45.6.78Local Port: 2249Local Port: 2249Remote Port: 3726Remote Port: 3726

Page 7: Network Programming Week #1 J.P. Yoo willow@konkuk.ac.kr

Sockets

• Identified by protocol and local/remote address/port

• Applications may refer to many sockets• Sockets accessed by many applications

Page 8: Network Programming Week #1 J.P. Yoo willow@konkuk.ac.kr

Creating a Socket

• create a resource for communication endpoint– socket call does not specify where data will be coming from, nor

where it will be going to – it just creates the interface!

• Socket reference– File (socket) descriptor in UNIX– Socket handle in WinSock

Family Type Protocol

TCPPF_INET

SOCK_STREAM IPPROTO_TCP

UDP SOCK_DGRAM IPPROTO_UDP

int socket(int family,int type,int proto);

Page 9: Network Programming Week #1 J.P. Yoo willow@konkuk.ac.kr

Two essential types of sockets

• SOCK_STREAM– a.k.a. TCP– reliable delivery– in-order guaranteed– connection-oriented– bidirectional

• SOCK_DGRAM– a.k.a. UDP– unreliable delivery– no order guarantees– no notion of

“connection” – app indicates dest. for each packet

– can send or receive

Page 10: Network Programming Week #1 J.P. Yoo willow@konkuk.ac.kr

Data I/O

int main() {int fd;fd = open( "data.dat", O_RDONLY,0);while( 1 ) {

write( fd, “test”,sizeof(“test”)+1 );}close( out );return 0;

}

int main() {int sockfd;sd = socket( PF_INET, SOCK_STREAM,0);while( 1 ) {

write( sd, “test”,sizeof(“test”)+1 );}close( out );return 0;

} To where?

Page 11: Network Programming Week #1 J.P. Yoo willow@konkuk.ac.kr

Specifying an Endpoint Addr.

• Sockets API is generic.• There must be a generic way to specify

endpoint addresses.• TCP/IP requires an IP address and a port

number for each endpoint address– We will deal with only TCP/IP suite– Other protocol suites (families) may use other

schemes

Page 12: Network Programming Week #1 J.P. Yoo willow@konkuk.ac.kr

TCP/IP Addresses

• We don’t need to deal with sockaddr structures since we will only deal with a real protocol family(TCP/IP).

• We can use sockaddr_in structures.

Page 13: Network Programming Week #1 J.P. Yoo willow@konkuk.ac.kr

• struct sockaddr {

unsigned short sa_family; /* Address family (e.g., AF_INET) */char sa_data[14]; /* Protocol-specific address information

*/};

• struct sockaddr_in{

unsigned short sin_family; /* Internet protocol (AF_INET) */ unsigned short sin_port; /* Port (16-bits) */ struct in_addr sin_addr; /* Internet address (32-bits) */ char sin_zero[8]; /* Not used */

}; struct in_addr{

unsigned long s_addr; /* Internet address (32-bits) */};

Gen

eri

cIP

Speci

fic

sockaddr

sockaddr_in

Family

Family Port

Blob

Internet address Not used

2 bytes 2 bytes 4 bytes 8 bytes

Page 14: Network Programming Week #1 J.P. Yoo willow@konkuk.ac.kr

Assigning an addr. to a socket

• The bind() system call is used to assign an address to an existing socket.

• bind returns 0 if successful or -1 on error.

int bind( int sockfd, struct sockaddr *localaddr, int addrlen);

Page 15: Network Programming Week #1 J.P. Yoo willow@konkuk.ac.kr

bind() Example

int mysock,err;struct sockaddr_in myaddr;char* servIP; /* ex)203.252.164.143 */

mysock = socket(PF_INET,SOCK_STREAM,0);myaddr.sin_family = AF_INET;myaddr.sin_port = htons( portnum );myaddr.sin_addr.s_addr = inet_addr(servIP);

err=bind(mysock, (sockaddr *) &myaddr, sizeof(myaddr));

Page 16: Network Programming Week #1 J.P. Yoo willow@konkuk.ac.kr

Socket Flow

Server

Socket()

Bind()

Client

Socket()Listen()

Accept()

Recv()

Send()

Connect()

Send()

Recv()

Block untilconnect

Processrequest

Connection Establishmt.

Data (request)

Data (reply)

Page 17: Network Programming Week #1 J.P. Yoo willow@konkuk.ac.kr

listen()

• Used by connection-oriented servers to indicate an application is willing to receive connections

int listen(int socket, int queuelimit)

– Socket: handle of newly creates socket• Only 1 for server

– queuelimit: number of connection requests that can be queued by the system while waiting for server to execute accept call.

Page 18: Network Programming Week #1 J.P. Yoo willow@konkuk.ac.kr

Accept()

int accept(int socket, struct sockaddr *clientdaddress, int addr_len)

• After executing listen, the accept() carries out a passive open – Create socket for the client which is doing

connect()

• it returns with a new socket that corresponds with new connection and the address contains the clients address

Page 19: Network Programming Week #1 J.P. Yoo willow@konkuk.ac.kr

Connect()

int connect(int socket, struct sockaddr *address, int addr_len)

• Client executes an active open of a connection

• Address field contains remote system’s address

• Client OS usually selects random, unused port

Page 20: Network Programming Week #1 J.P. Yoo willow@konkuk.ac.kr

• After connection has been made, application uses send/recv to data

int send(int socket, char *message, int msg_len, int flags)– Send specified message using specified socket

int recv(int scoket, char *buffer, int buf_len, int flags)– Receive message from specified socket into specified buffer

Send(to), Recv(from)

Page 21: Network Programming Week #1 J.P. Yoo willow@konkuk.ac.kr

Socket Flow(revisit)

Server

Socket()

Bind()

Client

Socket()Listen()

Accept()

Recv()

Send()

Connect()

Send()

Recv()

Block untilconnect

Processrequest

Connection Establishmt.

Data (request)

Data (reply)

Page 22: Network Programming Week #1 J.P. Yoo willow@konkuk.ac.kr

• Client: Initiates the connection

• Server: Passively waits to respond

Clients and Servers

Client: Bob

“Hi. I’m Bob.”

“Nice to meet you, Jane.”

Server: Jane

“Hi, Bob. I’m Jane”

Page 23: Network Programming Week #1 J.P. Yoo willow@konkuk.ac.kr

TCP Client/Server Interaction

Client1. Create a TCP socket2. Establish connection3. Communicate4. Close the connection

Server1. Create a TCP socket2. Assign a port to socket3. Set socket to listen4. Repeatedly:

a. Accept new connectionb. Communicatec. Close the connection

Server starts by getting ready to receive client connections…

Page 24: Network Programming Week #1 J.P. Yoo willow@konkuk.ac.kr

TCP Client/Server Interaction

Client1. Create a TCP socket2. Establish connection3. Communicate4. Close the connection

Server1. Create a TCP socket2. Bind socket to a port3. Set socket to listen4. Repeatedly:

a. Accept new connectionb. Communicatec. Close the connection

/* Create socket for incoming connections */ if ((servSock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) DieWithError("socket() failed");

Page 25: Network Programming Week #1 J.P. Yoo willow@konkuk.ac.kr

TCP Client/Server Interaction

Client1. Create a TCP socket2. Establish connection3. Communicate4. Close the connection

Server1. Create a TCP socket2. Bind socket to a port3. Set socket to listen4. Repeatedly:

a. Accept new connectionb. Communicatec. Close the connection

echoServAddr.sin_family = AF_INET; /* Internet address family */ echoServAddr.sin_addr.s_addr = htonl(INADDR_ANY);/* Any incoming interface */ echoServAddr.sin_port = htons(echoServPort); /* Local port */

if (bind(servSock, (struct sockaddr *) &echoServAddr, sizeof(echoServAddr)) < 0) DieWithError("bind() failed");

Page 26: Network Programming Week #1 J.P. Yoo willow@konkuk.ac.kr

TCP Client/Server Interaction

Client1. Create a TCP socket2. Establish connection3. Communicate4. Close the connection

Server1. Create a TCP socket2. Bind socket to a port3. Set socket to listen4. Repeatedly:

a. Accept new connectionb. Communicatec. Close the connection

/* Mark the socket so it will listen for incoming connections */ if (listen(servSock, MAXPENDING) < 0) DieWithError("listen() failed");

Page 27: Network Programming Week #1 J.P. Yoo willow@konkuk.ac.kr

TCP Client/Server Interaction

Client1. Create a TCP socket2. Establish connection3. Communicate4. Close the connection

Server1. Create a TCP socket2. Bind socket to a port3. Set socket to listen4. Repeatedly:

a. Accept new connectionb. Communicatec. Close the connection

for (;;) /* Run forever */{ clntLen = sizeof(echoClntAddr);

if ((clntSock=accept(servSock,(struct sockaddr *)&echoClntAddr,&clntLen)) < 0) DieWithError("accept() failed");

Page 28: Network Programming Week #1 J.P. Yoo willow@konkuk.ac.kr

TCP Client/Server Interaction

Client1. Create a TCP socket2. Establish connection3. Communicate4. Close the connection

Server1. Create a TCP socket2. Bind socket to a port3. Set socket to listen4. Repeatedly:

a. Accept new connectionb. Communicatec. Close the connection

Server is now blocked waiting for connection from a client

Later, a client decides to talk to the server…

Page 29: Network Programming Week #1 J.P. Yoo willow@konkuk.ac.kr

TCP Client/Server Interaction

Client1. Create a TCP socket2. Establish connection3. Communicate4. Close the connection

Server1. Create a TCP socket2. Bind socket to a port3. Set socket to listen4. Repeatedly:

a. Accept new connectionb. Communicatec. Close the connection

/* Create a reliable, stream socket using TCP */ if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) DieWithError("socket() failed");

Page 30: Network Programming Week #1 J.P. Yoo willow@konkuk.ac.kr

TCP Client/Server Interaction

Client1. Create a TCP socket2. Establish connection3. Communicate4. Close the connection

Server1. Create a TCP socket2. Bind socket to a port3. Set socket to listen4. Repeatedly:

a. Accept new connectionb. Communicatec. Close the connection

echoServAddr.sin_family = AF_INET; /* Internet address family */ echoServAddr.sin_addr.s_addr = inet_addr(servIP); /* Server IP address */ echoServAddr.sin_port = htons(echoServPort); /* Server port */

if (connect(sock, (struct sockaddr *) &echoServAddr, sizeof(echoServAddr)) < 0) DieWithError("connect() failed");

Page 31: Network Programming Week #1 J.P. Yoo willow@konkuk.ac.kr

TCP Client/Server Interaction

Client1. Create a TCP socket2. Establish connection3. Communicate4. Close the connection

Server1. Create a TCP socket2. Bind socket to a port3. Set socket to listen4. Repeatedly:

a. Accept new connectionb. Communicatec. Close the connection

if ((clntSock=accept(servSock,(struct sockaddr *)&echoClntAddr,&clntLen)) < 0) DieWithError("accept() failed");

Page 32: Network Programming Week #1 J.P. Yoo willow@konkuk.ac.kr

TCP Client/Server Interaction

Client1. Create a TCP socket2. Establish connection3. Communicate4. Close the connection

Server1. Create a TCP socket2. Bind socket to a port3. Set socket to listen4. Repeatedly:

a. Accept new connectionb. Communicatec. Close the connection

echoStringLen = strlen(echoString); /* Determine input length */

/* Send the string to the server */ if (send(sock, echoString, echoStringLen, 0) != echoStringLen) DieWithError("send() sent a different number of bytes than expected");

Page 33: Network Programming Week #1 J.P. Yoo willow@konkuk.ac.kr

TCP Client/Server Interaction

Client1. Create a TCP socket2. Establish connection3. Communicate4. Close the connection

Server1. Create a TCP socket2. Bind socket to a port3. Set socket to listen4. Repeatedly:

a. Accept new connectionb. Communicatec. Close the connection

/* Receive message from client */ if ((recvMsgSize = recv(clntSocket, echoBuffer, RCVBUFSIZE, 0)) < 0) DieWithError("recv() failed");

Page 34: Network Programming Week #1 J.P. Yoo willow@konkuk.ac.kr

TCP Client/Server Interaction

Client1. Create a TCP socket2. Establish connection3. Communicate4. Close the connection

Server1. Create a TCP socket2. Bind socket to a port3. Set socket to listen4. Repeatedly:

a. Accept new connectionb. Communicatec. Close the connection

close(sock); close(clntSocket)

Page 35: Network Programming Week #1 J.P. Yoo willow@konkuk.ac.kr

TCPEchoClient.c(1/2)#include <stdio.h> /* for printf() and fprintf() */

#include <sys/socket.h> /* for socket(), connect(), send(), and recv() */

#include <arpa/inet.h> /* for sockaddr_in and inet_addr() */

#include <stdlib.h> /* for atoi() and exit() */

#include <string.h> /* for memset() */

#include <unistd.h> /* for close() */

#define RCVBUFSIZE 32 /* Size of receive buffer */

void DieWithError(char *errorMessage); /* Error handling function */

int main(int argc, char *argv[]) {

int sock; /* Socket descriptor */

struct sockaddr_in echoServAddr; /* Echo server address */

unsigned short echoServPort; /* Echo server port */

char *servIP; /* Server IP address (dotted quad) */

char *echoString; /* String to send to echo server */

char echoBuffer[RCVBUFSIZE]; /* Buffer for echo string */

unsigned int echoStringLen; /* Length of string to echo */

int bytesRcvd, totalBytesRcvd; /* Bytes read in single recv()

and total bytes read */

if ((argc < 3) || (argc > 4)) /* Test for correct number of arguments */

{

fprintf(stderr, "Usage: %s <Server IP> <Echo Word> [<Echo Port>]\n",

argv[0]);

exit(1);

}

servIP = argv[1]; /* First arg: server IP address (dotted quad) */

echoString = argv[2]; /* Second arg: string to echo */

if (argc == 4)

echoServPort = atoi(argv[3]); /* Use given port, if any */

else

echoServPort = 7; /* 7 is the well-known port for the echo service */

/* Create a reliable, stream socket using TCP */

if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)

DieWithError("socket() failed");

/* Construct the server address structure */

memset(&echoServAddr, 0, sizeof(echoServAddr)); /* Zero out structure */

echoServAddr.sin_family = AF_INET; /* Internet address family */

echoServAddr.sin_addr.s_addr = inet_addr(servIP); /* Server IP address */

echoServAddr.sin_port = htons(echoServPort); /* Server port */

Page 36: Network Programming Week #1 J.P. Yoo willow@konkuk.ac.kr

TCPEchoClient.c(2/2)/* Establish the connection to the echo server */

if (connect(sock, (struct sockaddr *) &echoServAddr, sizeof(echoServAddr)) < 0)

DieWithError("connect() failed");

echoStringLen = strlen(echoString); /* Determine input length */

/* Send the string to the server */

if (send(sock, echoString, echoStringLen, 0) != echoStringLen)

DieWithError("send() sent a different number of bytes than expected");

/* Receive the same string back from the server */

totalBytesRcvd = 0;

printf("Received: "); /* Setup to print the echoed string */

while (totalBytesRcvd < echoStringLen)

{

/* Receive up to the buffer size (minus 1 to leave space for

a null terminator) bytes from the sender */

if ((bytesRcvd = recv(sock, echoBuffer, RCVBUFSIZE - 1, 0)) <= 0)

DieWithError("recv() failed or connection closed prematurely");

totalBytesRcvd += bytesRcvd; /* Keep tally of total bytes */

echoBuffer[bytesRcvd] = '\0'; /* Terminate the string! */

printf(echoBuffer); /* Print the echo buffer */

}

printf("\n"); /* Print a final linefeed */

close(sock);

exit(0);

Page 37: Network Programming Week #1 J.P. Yoo willow@konkuk.ac.kr

TCPEchoServer.c(1/2)#include <stdio.h> /* for printf() and fprintf() */

#include <sys/socket.h> /* for socket(), bind(), and connect() */

#include <arpa/inet.h> /* for sockaddr_in and inet_ntoa() */

#include <stdlib.h> /* for atoi() and exit() */

#include <string.h> /* for memset() */

#include <unistd.h> /* for close() */

#define MAXPENDING 5 /* Maximum outstanding connection requests */

void DieWithError(char *errorMessage); /* Error handling function */

void HandleTCPClient(int clntSocket); /* TCP client handling function */

int main(int argc, char *argv[])

{

int servSock; /* Socket descriptor for server */

int clntSock; /* Socket descriptor for client */

struct sockaddr_in echoServAddr; /* Local address */

struct sockaddr_in echoClntAddr; /* Client address */

unsigned short echoServPort; /* Server port */

unsigned int clntLen; /* Length of client address data structure */

if (argc != 2) /* Test for correct number of arguments */

{

fprintf(stderr, "Usage: %s <Server Port>\n", argv[0]);

exit(1);

}

echoServPort = atoi(argv[1]); /* First arg: local port */

/* Create socket for incoming connections */

if ((servSock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)

DieWithError("socket() failed");

/* Construct local address structure */

memset(&echoServAddr, 0, sizeof(echoServAddr)); /* Zero out structure */

echoServAddr.sin_family = AF_INET; /* Internet address family */

echoServAddr.sin_addr.s_addr = htonl(INADDR_ANY); /* Any incoming interface */

echoServAddr.sin_port = htons(echoServPort); /* Local port */

/* Bind to the local address */

if (bind(servSock, (struct sockaddr *) &echoServAddr, sizeof(echoServAddr)) < 0)

DieWithError("bind() failed");

/* Mark the socket so it will listen for incoming connections */

if (listen(servSock, MAXPENDING) < 0)

DieWithError("listen() failed");

Page 38: Network Programming Week #1 J.P. Yoo willow@konkuk.ac.kr

TCPEchoServer.c(2/2)for (;;) /* Run forever */

{

/* Set the size of the in-out parameter */

clntLen = sizeof(echoClntAddr);

/* Wait for a client to connect */

if ((clntSock = accept(servSock, (struct sockaddr *) &echoClntAddr,

&clntLen)) < 0)

DieWithError("accept() failed");

/* clntSock is connected to a client! */

printf("Handling client %s\n", inet_ntoa(echoClntAddr.sin_addr));

HandleTCPClient(clntSock);

}

/* NOT REACHED */

}

Page 39: Network Programming Week #1 J.P. Yoo willow@konkuk.ac.kr

HandleTCPClient.c#include <stdio.h> /* for printf() and fprintf() */

#include <sys/socket.h> /* for recv() and send() */

#include <unistd.h> /* for close() */

#define RCVBUFSIZE 32 /* Size of receive buffer */

void DieWithError(char *errorMessage); /* Error handling function */

void HandleTCPClient(int clntSocket)

{

char echoBuffer[RCVBUFSIZE]; /* Buffer for echo string */

int recvMsgSize; /* Size of received message */

/* Receive message from client */

if ((recvMsgSize = recv(clntSocket, echoBuffer, RCVBUFSIZE, 0)) < 0)

DieWithError("recv() failed");

/* Send received string and receive again until end of transmission */

while (recvMsgSize > 0) /* zero indicates end of transmission */

{

/* Echo message back to client */

if (send(clntSocket, echoBuffer, recvMsgSize, 0) != recvMsgSize)

DieWithError("send() failed");

/* See if there is more data to receive */

if ((recvMsgSize = recv(clntSocket, echoBuffer, RCVBUFSIZE, 0)) < 0)

DieWithError("recv() failed");

}

close(clntSocket); /* Close client socket */

}

Page 40: Network Programming Week #1 J.P. Yoo willow@konkuk.ac.kr

Winsock

#include <stdio.h> #include <winsock.h>#include <stdlib.h>

void main() {

WSADATA wsaData;

if (WSAStartup(MAKEWORD(2, 0), &wsaData) != 0) {fprintf(stderr, "WSAStartup() failed");

exit(1); }…closesocket(sock);

}

Page 41: Network Programming Week #1 J.P. Yoo willow@konkuk.ac.kr

Winsock

• for visual studio, you must add wsock32.lib manually– menu->project->settings->link->wsock32.lib */

Page 42: Network Programming Week #1 J.P. Yoo willow@konkuk.ac.kr

Assignment #0

• 앞의 client 코드와 Server 코드를 컴파일하여 동작을 확인하라– Linux 머신 혹은 windows 에서 cygwin 을

설치하였을 경우 동작한다 .• www.cygwin.com

– 필수 설치 패키지 – gcc 패키지

– Client Part• TcpEchoClient.c, DieWithError.c

– Server Part• TcpEchoServer.c, DieWithError.c, HandleTcpClient.c

Page 43: Network Programming Week #1 J.P. Yoo willow@konkuk.ac.kr

Gcc 컴파일 법

• #gcc –o client TcpEchoClient.c DieWithError.c

Output binary filename Source files

Page 44: Network Programming Week #1 J.P. Yoo willow@konkuk.ac.kr

Assignment #1

• 기본 과제– 앞의 예제를 수정하여 다음의 기능을 가지는

프로그램을 작성하라• 서버는 클라이언트의 문자열을 화면에 출력한다 .• 서버는 클라이언트의 문자열을 동시에 파일로 저장한다 .

파일이름은 echo_history.log 이며 append 로 계속 추가되게 한다 .

• Challenge– 파일의 소유권 , permission 등도 유지가되도록하라 .