網路程式設計 - socket 程式設計

Post on 26-Jan-2016

135 Views

Category:

Documents

9 Downloads

Preview:

Click to see full reader

DESCRIPTION

網路程式設計 - Socket 程式設計. 蔡進義 cyt@pmlab.iecs.fcu.edu.tw. 大綱. TCP/IP 協定複習 什麼是 Socket Socket API 的使用 Socket 相関資料的結構 常用 Socket API. TCP / IP 協定 複習. FTP , SMTP , Telnet , DNS , SNMP. What is TCP / IP Transmission Control Protocol / Internet Protocol. TCP , UDP. 應用層. Application. - PowerPoint PPT Presentation

TRANSCRIPT

網路程式設計網路程式設計 --SocketSocket 程式設計程式設計

蔡進義 蔡進義 cyt@pmlab.iecs.fcu.edu.tw cyt@pmlab.iecs.fcu.edu.tw

22

大綱大綱 TCP/IP 協定複習

什麼是 Socket

Socket API 的使用

Socket 相関資料的結構

常用 Socket API

33

TCP / IPTCP / IP 協定協定複習複習 What is TCP / IP What is TCP / IP Transmission Control Protocol / Internet Protocol Transmission Control Protocol / Internet Protocol

網路存取層網路存取層

網路層網路層

傳輸層傳輸層

應用層應用層

Network Access Network Access

Network Network

Transport Transport

Application Application

FTP , SMTP , Telnet , DNS , SNMP

TCP , UDP

IP , ARP

Ethernet , FDDI , Token Ring

44

Port(Port( 埠埠 ) ) 每一台主機有每一台主機有 6553665536 個個 portsports

• port 0 ~ port 65535port 0 ~ port 65535

一些保留的一些保留的 portsports• 20, 21: FTP20, 21: FTP• 23: Telnet23: Telnet• 80: HTTP80: HTTP

未保留未保留• 1024 ~ 50001024 ~ 5000

Port 1

Port 2

Port 65535

Port 0

Port 3

Port 3333 Port 3333

Port 80 Port 80

55

大綱大綱 TCP/IPTCP/IP 協定複習協定複習

什麼是什麼是 SocketSocket

Socket APISocket API 的使用 的使用

SocketSocket 相関資料的結構 相関資料的結構

常用常用 Socket API Socket API

66

什麼是什麼是 SocketSocket ?? SocketSocket 首次出現在首次出現在 Berkeley UNIXBerkeley UNIX 中,作為網路設計中,作為網路設計 TCP/IPTCP/IP 的橋樑的橋樑

SocketSocket 是一個簡單的應用程式介面是一個簡單的應用程式介面 (Application Programming (Application Programming Interface, API)Interface, API)

SocketSocket 使發展網路程式變得比較簡單。目前,使發展網路程式變得比較簡單。目前, SocketSocket 已成為最通用的已成為最通用的網路設計介面了。 網路設計介面了。

Berkeley Socket InterfaceBerkeley Socket Interface 是一組是一組 interface functioninterface function ,介於網路應用,介於網路應用程式和作業系統及網路硬體之間,用以提供標準的函數,應用程式可透過程式和作業系統及網路硬體之間,用以提供標準的函數,應用程式可透過呼叫呼叫 Socket interfaceSocket interface 以發展以發展 TCP/IPTCP/IP 的網路應用程式。 的網路應用程式。

BSD ( Berkeley Software Distribution ) Socket BSD ( Berkeley Software Distribution ) Socket

WinSock WinSock

LINK

77

應用程式與應用程式與 SocketSocket 關係關係

應用程式 1應用程式 1 應用程式 2應用程式 2 應用程式 3應用程式 3 應用程式 4應用程式 4

網路程式介面 API (BSD Socket 或 Win Sock)網路程式介面 API (BSD Socket 或 Win Sock)

TCP/IPTCP/IP

作業系統作業系統

網路卡網路卡

88

SocketSocket 概念概念 SocketSocket 的概念和檔案代碼觀念相似,一個的概念和檔案代碼觀念相似,一個 SocketSocket

就是一個通訊點,以一個就是一個通訊點,以一個整數整數來表示之。來表示之。

SocketSocket 並不是並不是 TCPTCP 或或 UDPUDP 的的 port numberport number

SocketSocket 只是一個代碼代表網路協定中的只是一個代碼代表網路協定中的一組資料一組資料• TCPTCP 連線中雙方的連線中雙方的 IPIP 位址位址• 目前連線的狀態目前連線的狀態

99

Socket DescriptorSocket Descriptor

Socket( 整數 )

1010

主機1主機1 主機 2主機 2

TCP 或 UDPTCP 或 UDP

AP1AP1 AP2AP2 AP3AP3 AP3AP3

80 333321 23

1111

大綱大綱 TCP/IPTCP/IP 協定複習協定複習

什麼是什麼是 Socket?Socket?

Socket APISocket API 的使用的使用

SocketSocket 相關的資料結構相關的資料結構

主要的主要的 Socket APISocket API

1212

Socket(Socket( 連結導向連結導向 ), TCP), TCP

socket()socket()

connect()connect()

write()write()

read()read()

socket()socket()

bind()bind()

read()read()

write()write()

listen()listen()

accept()accept()

建立連線Client Server

1313

write()

write()

read()

read()

使用 write() 及 read() 來傳送與接收資料

1414

Socket(Socket( 非連結導向非連結導向 ), UDP), UDP

socket()socket()

bind()bind()

sendto()sendto()

recvfrom()recvfrom() sendto()sendto()

Client Server

socket()socket()

bind()bind()

recvfrom()recvfrom()

1515

Client/ServerClient/Server 模型模型 ClientClient 端:端:1.1. ClientClient 開啟一個開啟一個 socketsocket 並且使用一個並且使用一個 portport

2.2. ClientClient 使用使用 connectconnect 以建立連結以建立連結 TCPTCP 要經過三向交握要經過三向交握

3.3. ClientClient 使用使用 read/write system callread/write system call 對開啟的對開啟的 socketsocket 做讀做讀寫的動作寫的動作

4.4. 關閉關閉 socketsocket 以結束連結以結束連結

1616

open socket 由作業系統如同檔案一般取得一 Socket Descriptor ,讓 Client 端以後可使用這一代號進行網路I/O 讀寫。

bind 是指定 Client 端使用 local ( 也就是本機 ) 的哪一 IP及 Port 進行通訊。若無指定,則連線時由系統幫 Client 程式自動挑選合適的 IP 與 Port 。因此對 Client 端而言是 Optional 。

connect 是起始 TCP 的連線,配合 Server 端的 accept System Call 完成三向交握,因此於 connect 此 System Call 必需傳給予對方 Server 端的 IP 與 Port 的資訊。

read/write 針對已經完成連線的 Socket Descriptor 進行 I/O 動作,在此傳送 HTTP 的 Protocol 並得到 Server 回傳的 HTML 檔案內容等。

close 關閉 TCP 連線,釋放系統資源。

socket()socket()

bind()bind()

connect()connect()

read()write()read()write()

close()close()

1717

Client/ServerClient/Server 模型模型 ServerServer 端:端:1.1. ServerServer 開啟一個開啟一個 socketsocket 並佔用一個並佔用一個 portport

2.2. 使使 socketsocket 進入被動模式來等待進入被動模式來等待 clientclient 的連結的連結

3.3. ServerServer 及及 clientclient 利用利用 read/write system callread/write system call 進行對開啟進行對開啟的的 socketsocket 做讀寫的動作做讀寫的動作

4.4. 關閉關閉 socketsocket 以結束連結以結束連結

1818

open socket 由作業系統如同檔案一般取得一 Socket Descriptor ,讓 Server 端以後可使用這一代號進行接受外來 TCP 連線。

bind 是指定 Server 端使用 local 的哪一 IP 及 Port 進行通訊。對 Server 端而言是必需的。

listen 表示讓此開啟的 Socket 進入被動模式,配合 accept System Call 可接受外來之連線。

Server 端的 accept System Call 接受 Client 之 connect System Call 完成三向交握,並產生一新的 Descriptor ,此 Descriptor 即為與 Client 進行 I/O 的代號。

read/write 針對已經 accept 產生之 Descriptor 進行 I/O 動作,在此傳送 HTTP 的 Protocol 並得到 Server 回傳的 HTML 檔案內容等。

close 關閉 TCP 連線,釋放系統資源。

socket()socket()

bind()bind()

listen()listen()

read()write()read()write()

close()close()

accept()accept()

1919

範例範例 (Client(Client 端端 ) 1/2) 1/2// 建立 socket ,若成功傳回 socket descriptor ,若傳回 -1 表 error if((sockfd=socket(AF_INET, SOCK_STREAM, 0)) == -1) { printf("Socket Error:%s\a\n", strerror(errno)); printf("Socket Error:%s\a\n", strerror(errno)); exit(1); } // 填入 family, address, port ,另外,其他地方要填入 0( 使用 bzero() function) bzero((char*) &server_addr, sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_port = htons(portnumber); server_addr.sin_addr = *((struct in_addr *) host->h_addr); // 和 Server 建立連線 if(connect(sockfd, (struct sockaddr *)(&server_addr), sizeof(struct sockaddr)) == -1) { printf("Connect Error:%s\a\n", strerror(errno)); exit(1); }

140.134.26.50

Most Significant byte first (Network Byte Order)

Least Significant byte first ( 大部分 Host Byte Order)

140 134 26 50

50 26 134 140

2020

範例範例 (Client(Client 端端 ) 2/2) 2/2// 送資料 (hello 字串 ) 給 Server if(write(sockfd, hello, strlen(hello)) == -1) { printf("Write Error:%s\n", strerror(errno)); exit(1); } // 從 Server 收資料 if((nbytes=read(sockfd, buffer, 1024)) == -1) { printf("Read Error:%s\n", strerror(errno)); exit(1); } buffer[nbytes] = '\0'; printf("I am Client. I have received from Server:%s\n", buffer); close(sockfd); exit(0);

2121

範例範例 (Server(Server 端端 ) 1/3) 1/3// 建立 socket ,若成功傳回 socket descriptor ,若傳回 -1 表 error if((sockfd=socket(AF_INET,SOCK_STREAM,0)) == -1) { printf("Socket error:%s\n\a", strerror(errno)); exit(1); } // 填入 family, address, port ,另外,其他地方要填入 0( 使用 bzero() function) bzero((char*)&server_addr,sizeof(struct sockaddr_in)); server_addr.sin_family = AF_INET; server_addr.sin_port = htons(portnumber); //port number, 以 htons(16 bytes) 轉成 network byte order server_addr.sin_addr.s_addr = htonl(INADDR_ANY); //htonl is for 32-bytes, binary presentation // 連接通訊埠 if(bind(sockfd, (struct sockaddr *)(&server_addr), sizeof(struct sockaddr)) == -1) { printf("Bind error:%s\n\a", strerror(errno)); exit(1); }

2222

範例範例 (Server(Server 端端 ) 2/3) 2/3// 進入被動狀態,等待連線 if(listen(sockfd,5) == -1) { printf("Listen error:%s\n\a", strerror(errno)); exit(1); }

while(1) { sin_size = sizeof(struct sockaddr_in); // 接受連線,並產生一個新的 socket(new_fd) ,傳回 -1 表失敗 // 其中 client 的 address 將放在 client_addr 中 if((new_fd=accept(sockfd, (struct sockaddr *)(&client_addr), &sin_size)) == -1) { fprintf(stderr, "Accept error:%s\n\a", strerror(errno)); exit(1); }

printf("Server get connection from %s\n", inet_ntoa(client_addr.sin_addr));

2323

範例範例 (Server(Server 端端 ) 3/3) 3/3// 將資料讀進放入 buffer 陣列中 if((nbytes=read(new_fd, buffer, 1024)) == -1) { printf("Read Error:%s\n", strerror(errno)); exit(1); } buffer[nbytes] = '\0'; printf("I have received:%s\n", buffer); // 把 hello 字串的資料傳回 client if(write(new_fd, hello, strlen(hello)) == -1) { printf("Write Error:%s\n", strerror(errno)); exit(1); } close(new_fd); } close(sockfd); exit(0);

2424

2525

大綱大綱 TCP/IPTCP/IP 協定複習協定複習

什麼是什麼是 Socket?Socket?

Socket APISocket API 的使用的使用

SocketSocket 相關的資料結構相關的資料結構

主要的主要的 Socket APISocket API

2626

SocketSocket 相關資料結構相關資料結構 struct    sockaddr struct    sockaddr struct    sockaddr_instruct    sockaddr_in struct    in_addrstruct    in_addr struct    hostentstruct    hostent struct    serventstruct    servent struct    protoentstruct    protoent

2727

sockaddr sockaddr

<sys/socket.h>

// 一般化的位址struct sockaddr {   

u_short         sa_family;   /* type of address, AF_INET, AF_INET (Internet protocol address family) */char              sa_data[14];              /* value of address, specifies the address value */

};

2828

sockaddr_in sockaddr_in

<netinet/in.h>

//IPv4 Socket Addressstruct sockaddr_in {                           

u_short                  sin_family;           //specifies protocol to use, PF_INET for either of TCP or UDPu_port                   sin_port;             //16 bits, network byte orderstruct in_addr      sin_addr;             //32 bits, network byte order

    char                      sin_zero[8];         //unused

};

2929

一般位址一般位址 IPv4 Socket AddressIPv4 Socket Address

3030

in_addr

//Internet address structure struct in_addr {                             

long           s_addr;                 //32-bit( 整數 ) IPv4 address, network byte ordered

};

3131

hostentstruct hostent {

char               *h_name;    char               **h_aliases;    int                  h_addrtype;    int                  h_length;    char               **h_addr_list;                       

//hptr->h_addr = gethostbyname(“140.134.26.21”);};

#define      h_addr              h_addr_list[0]

h_addr_list[0]

h_addr_list[1]

h_addr_list

……

3232

servent servent

struct servent {    char         *s_name;

char         **s_aliases;    int            s_port;    char         *s_proto;};

3333

protoent protoent

struct protoent {    char       *p_name;    char       **p_aliases;    int          p_proto;};

3434

大綱大綱 TCP/IPTCP/IP 協定複習協定複習

什麼是什麼是 Socket?Socket?

Socket APISocket API 的使用的使用

SocketSocket 相關的資料結構相關的資料結構

主要的主要的 Socket APISocket API

3535

主要的主要的 Socket APISocket API socketsocket

• 建立建立 socketsocket bindbind

• 設定設定 socketsocket 所使用的所使用的 local IPlocal IP 及通訊埠及通訊埠 listenlisten

• 設定設定 socketsocket 等待等待 clientclient 的連結請求的連結請求 acceptaccept

• 接受來自接受來自 clientclient 的連結請求,並建立的連結請求,並建立 socketsocket 連結連結 recv/readrecv/read

• (TCP)(TCP) 接收來自接收來自 clientclient 所傳的資料所傳的資料 recvfromrecvfrom

• (UDP)(UDP) 接收來自接收來自 clientclient 所傳的資料所傳的資料 send/writesend/write

• (TCP)(TCP) 傳送資料到傳送資料到 clientclient sendtosendto

• (UDP)(UDP) 傳送資料到傳送資料到 clientclient

Server

3636

主要的主要的 Socket APISocket API socketsocket

• 建立建立 socketsocket connectconnect

• 建立與建立與 serverserver 端端 socketsocket 連線 連線 recv/readrecv/read

• (TCP)(TCP) 接收來自接收來自 serverserver 所傳的資料 所傳的資料 recvfromrecvfrom

• (UDP)(UDP) 接收來自接收來自 serverserver 所傳的資料 所傳的資料 send/writesend/write

• (TCP)(TCP) 傳送資料到傳送資料到 server server sendtosendto

• (UDP)(UDP) 傳送資料到傳送資料到 server server

Client

3737

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

參數:family: Selects the protocol family to be used; defined in <sys/socket.h>; use PF_INET for TCP or UDP. 其他還有 PF_UNIXAF_INET          IPv4AF_INET6        IPv6AF_LOCAL      Unix domain protocols ~ IPCAF_ROUTE      Routing sockets ~ appls and kernelAF_KEY           Key socketAF_UNIXAF_IMPLINKtype: Semantics of desired communication protocol; defined in <sys/socket.h>; SOCK_STREAM for TCP; SOCK_DGRAM for UDP; others are possible.SOCK_STREAM     stream socketSOCK_DGRAM      datagram socketSOCK_RAW           raw socketSOCK_PACKET     datalink (Linux)protocol: Normally only one per type; defined in /etc/protocols; 6 for TCP, 17 for UDP; Can use 0 (zero) and the socket call will figure out the right protocol to use for the specified type field. 傳回值:Return: return a integer identifier called a handle. (nonnegative descriptor if OK, negative number on error) 範例:Example:  To create a TCP socket:    int sock;    sock = socket(PF_INET, SOCK_STREAM, 0);

3838

int connect(int s, struct sockaddr *name, int namelen); int connect(int s, struct sockaddr *name, int namelen);

參數:s: file descriptor of socket; returned by call to socket.name: address of the socket data structure; must fill-in this structure before calling connect.namelen: length of name data structure; sizeof(name).

範例:Example:if(connect(fd, (struct sockaddr*) &srv, sizeof(srv)) < 0) {    perror(”connect"); exit(1);}

3939

int bind(int socket, const struct sockaddr *address, int addrlen); int bind(int socket, const struct sockaddr *address, int addrlen);

功能:Server 端的 TCP 或 UDP 會使用到連結 socket 到特定的 address (IP address & TCP/UDP port)

參數:socket: Descriptor identifying an unbound socket. (returned by the socket function.)address: A pointer to a protocol-specific addressaddrlen: Length of the value in the name parameter, in bytes.

範例:Example:if(bind(fd, (struct sockaddr*) &srv, sizeof(srv)) < 0) {    perror("bind");     exit(1);}

4040

int listen(int s, int backlog); int listen(int s, int backlog);

if(listen(fd, 5) < 0) {    perror(“listen”);    exit(1);}

4141

int accept(int s, struct sockaddr *addr, socklen_t int accept(int s, struct sockaddr *addr, socklen_t *addrlen);*addrlen);

參數:s: the socket the Server is listening to.addr will be the address (IP + port) of the client that sent the connection request.

傳回值:Return: (new) socket for communicating with this client. 範例:Example:newfd = accept(fd, (struct sockaddr*) &cli, &cli_len);if(newfd < 0) {    perror("accept"); exit(1);}

4242

int send (int socket, char *message, int msg_len, intflags) (TCP) int send (int socket, char *message, int msg_len, intflags) (TCP)

int write(int socket, void *msg, int len); (TCP) int write(int socket, void *msg, int len); (TCP)

int recv (int socket, char *buffer, int buf_len, int flags) (TCP) int recv (int socket, char *buffer, int buf_len, int flags) (TCP)

4343

int read(int socket, void *msg, int len); (TCP) int read(int socket, void *msg, int len); (TCP)

範例:Example:int fd;                    /* socket descriptor */char buf[512];       /* used by read() */int nbytes;             /* used by read() */if((nbytes = read(newfd, buf, sizeof(buf))) < 0) {    perror(“read”);     exit(1);}

4444

int sendto (int socket, void *msg, int len, int flags, struct int sendto (int socket, void *msg, int len, int flags, struct sockaddr * to, int tolen ); (UDP) sockaddr * to, int tolen ); (UDP)

參數:socket: Descriptor identifying a bound socket.msg: Buffer containing the data to be transmitted.len: Length of the data in buf, in bytes. flags: Indicator specifying the way in which the call is made. (usually set to 0)to: Optional pointer to a sockaddr structure that contains the address of the target socket. tolen: Size of the address in to, in bytes.

範例:Example:int fd;                                  /* socket descriptor */struct sockaddr_in srv;         /* used by sendto() */srv.sin_family = AF_INET;srv.sin_port = htons(80); srv.sin_addr.s_addr = inet_addr(“128.2.35.50”);nbytes = sendto(fd, buf, sizeof(buf), 0 , (struct sockaddr*) &srv, sizeof(srv));if(nbytes < 0) {    perror(“sendto”); exit(1);}

4545

int recvfrom(int socket, void *msg, int len, int flags, struct int recvfrom(int socket, void *msg, int len, int flags, struct sockaddr *from, int *fromlen); (UDP) sockaddr *from, int *fromlen); (UDP)

範例:Example:int fd;                                    /* socket descriptor */struct sockaddr_in srv;          /* used by bind() */struct sockaddr_in cli;           /* used by recvfrom() */char buf[512];                       /* used by recvfrom() */int cli_len = sizeof(cli);         /* used by recvfrom() */int nbytes;                             /* used by recvfrom() */nbytes = recvfrom(fd, buf, sizeof(buf), 0 /* flags */,

(struct sockaddr*) &cli, &cli_len);if(nbytes < 0) {    perror(“recvfrom”); }

4646

unsigned long int htonl(unsigned long int hostlong);unsigned long int htonl(unsigned long int hostlong);• Host-to-network byte order for a long word (4 bytes) Host-to-network byte order for a long word (4 bytes)

unsigned short int htons(unsigned short int hostshort);unsigned short int htons(unsigned short int hostshort);• Host-to-network byte order for a short word (2 bytes) Host-to-network byte order for a short word (2 bytes)

unsigned long int ntohl(unsigned long int netlong);unsigned long int ntohl(unsigned long int netlong);• Network-to-host byte order for a long word Network-to-host byte order for a long word

unsigned short int ntohs(unsigned short int netshort);unsigned short int ntohs(unsigned short int netshort);• Network-to-host byte order for a short word Network-to-host byte order for a short word

4747

struct hostent *gethostbyname (const char *hostname); struct hostent *gethostbyname (const char *hostname);

定義在 <netdb.h> 中struct hostent {    char           *h_name;                /* official (canonical) name of host */    char           **h_aliases;            /* ptr to array of ptrs to alias names */    int              h_addrtype;               /* host addr type: AF_INET or AF_INET6 */    int              h_length;                    /* length of address: 4 or 16 */    char           **h_addr_list;         /* ptr to array of ptrs with IPv4/IPv6 addrs */};#define h_addr h_addr_list[0] /* first address in list */

top related