9.소켓 프로그래밍

1.소켓 프로그래밍 개요

2.서버/클라이언트

SYNOPSIS

#include <sys/types.h>

#include <sys/socket.h>

int socket(int domain, int type, int protocol);

DESCRIPTION

Socket creates an endpoint for communication and returns a

descriptor.

The domain parameter  specifies  a  communication  domain;

this  selects  the  protocol family which will be used for

communication.    These   families    are    defined    in

<sys/socket.h>.  The currently understood formats include:

Name               Purpose                          Man page

PF_UNIX,PF_LOCAL   Local communication              unix(7)

PF_INET            IPv4 Internet protocols          ip(7)

PF_INET6           IPv6 Internet protocols

PF_IPX             IPX - Novell protocols

PF_NETLINK         Kernel user interface device     netlink(7)

PF_X25             ITU-T X.25 / ISO-8208 protocol   x25(7)

PF_AX25            Amateur radio AX.25 protocol

PF_ATMPVC          Access to raw ATM PVCs

PF_APPLETALK       Appletalk                        ddp(7)

PF_PACKET          Low level packet interface       packet(7)

The  socket  has  the  indicated type, which specifies the

communication semantics.  Currently defined types are:

SOCK_STREAM

Provides sequenced, reliable, two-way,  connection-

based  byte streams.  An out-of-band data transmis□

sion mechanism may be supported.

SOCK_DGRAM

Supports datagrams (connectionless, unreliable mes□

sages of a fixed maximum length).

SOCK_SEQPACKET

Provides a sequenced, reliable, two-way connection-

based data transmission path for datagrams of fixed

maximum  length;  a consumer is required to read an

entire packet with each read system call.

SOCK_RAW

Provides raw network protocol access.

SOCK_RDM

Provides a reliable datagram layer  that  does  not

guarantee ordering.

SOCK_PACKET

Obsolete  and  should  not be used in new programs;

see packet(7).

Some socket types may not be implemented by  all  protocol

families;  for  example, SOCK_SEQPACKET is not implemented

for AF_INET.

RETURN VALUES

-1 is returned if an error occurs;  otherwise  the  return

value is a descriptor referencing the socket.

SYNOPSIS

#include <sys/types.h>

#include <sys/socket.h>

int  getsockopt(int  s, int level, int optname, void *opt□

val, socklen_t *optlen);

int setsockopt(int s, int level, int optname,  const  void

*optval, socklen_t optlen);

DESCRIPTION

Getsockopt  and  setsockopt manipulate the options associ□

ated with a socket.  Options may exist at multiple  proto□

col  levels;  they  are  always  present  at the uppermost

socket level.

RETURN VALUE

On success, zero is returned.  On error, -1  is  returned,

and errno is set appropriately.

SYNOPSIS

#include <sys/types.h>

#include <sys/socket.h>

int  bind(int  sockfd, struct sockaddr *my_addr, socklen_t

addrlen);

DESCRIPTION

bind gives the socket sockfd the  local  address  my_addr.

my_addr  is  addrlen  bytes  long.  Traditionally, this is

called "assigning a name to a socket."  When a  socket  is

created with socket(2), it exists in a name space (address

family) but has no name assigned.

SYNOPSIS

#include <sys/socket.h>

int listen(int s, int backlog);

DESCRIPTION

To  accept  connections,  a  socket  is first created with

socket(2), a willingness to  accept  incoming  connections

and  a  queue limit for incoming connections are specified

with listen, and then the connections  are  accepted  with

accept(2).   The  listen  call  applies only to sockets of

type SOCK_STREAM or SOCK_SEQPACKET.

RETURN VALUE

On  success,  zero is returned.  On error, -1 is returned,

and errno is set appropriately.

SYNOPSIS

#include <sys/types.h>

#include <sys/socket.h>

int   accept(int   s,  struct  sockaddr  *addr,  socklen_t

*addrlen);

DESCRIPTION

The accept function is used with  connection-based  socket

types  (SOCK_STREAM,  SOCK_SEQPACKET  and  SOCK_RDM).   It

extracts the first connection  request  on  the  queue  of

pending  connections,  creates a new connected socket with

mostly the same properties as s, and allocates a new  file

descriptor  for  the socket, which is returned.  The newly

created socket is no longer in the listening  state.   The

original  socket  s  is unaffected by this call. Note that

any per file descriptor flags (everything that can be  set

with  the F_SETFL fcntl, like non blocking or async state)

are not inherited across a accept.

RETURN VALUES

The call returns -1 on error.  If it succeeds, it  returns

a  non-negative  integer  that  is  a  descriptor  for the

accepted socket.

SYNOPSIS

#include <sys/types.h>

#include <sys/socket.h>

int recv(int s, void *buf, size_t len, int flags);

int  recvfrom(int  s,  void  *buf,  size_t len, int flags,

struct sockaddr *from, socklen_t *fromlen);

int recvmsg(int s, struct msghdr *msg, int flags);

DESCRIPTION

The recvfrom and recvmsg calls are used  to  receive  mes□

sages  from a socket, and may be used to receive data on a

socket whether or not it is connection-oriented.

RETURN VALUES

These  calls return the number of bytes received, or -1 if

an error occurred.

SYNOPSIS

#include <sys/types.h>

#include <sys/socket.h>

int send(int s, const void *msg, size_t len, int flags);

int  sendto(int s, const void *msg, size_t len, int flags,

const struct sockaddr *to, socklen_t tolen);

int sendmsg(int s, const struct msghdr *msg, int flags);

DESCRIPTION

Send, sendto, and sendmsg are used to transmit  a  message

to  another socket.  Send may be used only when the socket

is in a connected state, while sendto and sendmsg  may  be

used at any time.

RETURN VALUES

The calls return the number of characters sent, or  -1  if

an error occurred.

ex)server.c

#include <arpa/inet.h>

#include <netinet/in.h>

#include <stdio.h>

#include <sys/socket.h>

#include <unistd.h>

#include <string.h>

#include <stdlib.h>

#include <sys/time.h>

#include <sys/types.h>

#include <sys/stat.h>

int main(void)

{

//----- variables -----//

struct sockaddr_in address;

int sock, conn, i, curr;

int childpid;

size_t addrLength = sizeof(struct sockaddr_in);

char buff[512];

//----- socket operations -----//

// create listen socket //

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

{

printf("[Err] socket creation error\n");

return 1;

}

// set socket option //

i=1;

setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i));

// set address information //

address.sin_family = AF_INET;

address.sin_port = htons(2714);

memset(&address.sin_addr, 0, sizeof(address.sin_addr));

// bind address //

if(bind(sock, (struct sockaddr *)&address, sizeof(address)))

{

printf("[Err] bind address error\n");

return 1;

}

// listen //

if(listen(sock, 5))

{

printf("[Err] listen error\n");

return 1;

}

// accept socket //

conn = accept(sock, (struct sockaddr *)&address, &addrLength);

{

// notify //

printf("[Log] new connection\n");

//----- set current socket -----//

curr = conn;

//----- receive data from socket -----//

while(1)

{

// receive request from client //

recv(curr, buff, 512, 0);

printf("receive data %s\n",buff);

gets(buff);

printf("send data:%s\n",buff);

send(curr, buff, 512, 0);

if(strstr(buff,"end"))

break;

}

}

// close listeing socket //

close(sock);

return 0;

}

ex)client.c

#include <arpa/inet.h>

#include <netinet/in.h>

#include <stdio.h>

#include <sys/socket.h>

#include <unistd.h>

#include <string.h>

#include <stdlib.h>

#include <sys/time.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <netdb.h>

int main(void)

{

//----- variables -----//

struct sockaddr_in address;

int sock;

size_t addrLength = sizeof(struct sockaddr_in);

char buff[512];

struct hostent *hostname;

hostname=gethostbyname("vision.hanyang.ac.kr");

bzero(&address,sizeof(address));

address.sin_family=AF_INET;

address.sin_addr.s_addr=htonl(INADDR_ANY);

address.sin_addr.s_addr=((struct in_addr *)(hostname->h_addr))->s_addr;

address.sin_port=htons(2714);

//----- socket operations -----//

if((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)

{

printf("[Err] socket creation error\n");

return 1;

}

connect(sock,(void *)&address,sizeof(address));

strcpy(buff,"hi! this is client");

send(sock,buff,strlen(buff)+1,0);

while(1)

{

if(recv(sock,buff,512,0)>0)

{

printf("%s",buff);

}

gets(buff);

if(strlen(buff)>0)

{

send(sock,buff,strlen(buff)+1,0);

}

if(strstr(buff,"end"))

break;

}

// close listeing socket //

close(sock);

return 0;

}

3.진보적인 예제

서버

#include <arpa/inet.h>

#include <netinet/in.h>

#include <stdio.h>

#include <sys/socket.h>

#include <unistd.h>

#include <string.h>

#include <stdlib.h>

#include <sys/time.h>

#include <sys/types.h>

#include <sys/stat.h>

int main(void)

{

//----- variables -----//

struct sockaddr_in address;

int sock, conn, i, curr;

int childpid;

size_t addrLength = sizeof(struct sockaddr_in);

char buff[512];

//----- socket operations -----//

// create listen socket //

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

{

printf("[Err] socket creation error\n");

return 1;

}

// set socket option //

i=1;

setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i));

// set address information //

address.sin_family = AF_INET;

address.sin_port = htons(2714);

memset(&address.sin_addr, 0, sizeof(address.sin_addr));

// bind address //

if(bind(sock, (struct sockaddr *)&address, sizeof(address)))

{

printf("[Err] bind address error\n");

return 1;

}

// listen //

if(listen(sock, 5))

{

printf("[Err] listen error\n");

return 1;

}

// accept socket //

conn = accept(sock, (struct sockaddr *)&address, &addrLength);

{

// notify //

printf("[Log] new connection\n");

//----- set current socket -----//

curr = conn;

childpid= fork();

//----- receive data from socket -----//

while(1)

{

// receive request from client //

if(childpid==0)

{

recv(curr, buff, 512, 0);

printf("receive data %s\n",buff);

}

else

{

gets(buff);

printf("send data:%s\n",buff);

send(curr, buff, 512, 0);

}

if(strstr(buff,"end"))

break;

}

}

// close listeing socket //

close(sock);

return 0;

}

클라이언트

#include <arpa/inet.h>

#include <netinet/in.h>

#include <stdio.h>

#include <sys/socket.h>

#include <unistd.h>

#include <string.h>

#include <stdlib.h>

#include <sys/time.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <netdb.h>

int main(void)

{

//----- variables -----//

struct sockaddr_in address;

int sock,childpid;

size_t addrLength = sizeof(struct sockaddr_in);

char buff[512];

struct hostent *hostname;

hostname=gethostbyname("vision.hanyang.ac.kr");

bzero(&address,sizeof(address));

address.sin_family=AF_INET;

address.sin_addr.s_addr=htonl(INADDR_ANY);

address.sin_addr.s_addr=((struct in_addr *)(hostname->h_addr))->s_addr;

address.sin_port=htons(2714);

//----- socket operations -----//

if((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)

{

printf("[Err] socket creation error\n");

return 1;

}

connect(sock,(void *)&address,sizeof(address));

strcpy(buff,"hi! this is client");

send(sock,buff,strlen(buff)+1,0);

childpid=fork();

while(1)

{

if(childpid == 0)

{

if(recv(sock,buff,512,0)>0)

{

printf("%s\n",buff);

}

}

else

{

gets(buff);

if(strlen(buff)>0)

{

send(sock,buff,strlen(buff)+1,0);

}

}

if(strstr(buff,"end"))

break;

}

// close listeing socket //

close(sock);

return 0;

}