Advister: Quincy Wu Speaker: Chenglin Tsai Date:3/26 Socket Programming Advister: Quincy Wu Speaker: Chenglin Tsai Date:3/26 2019/4/11
Socket Interface Socket是一種通訊的機制,可以開發本地或跨越網路的Client/Server系統 Socket 界面 FTP 伺服器 SSH SMTP Web 瀏覽器 TCP ports 20.21 TCP port 22 25 0…65536 TCP IP UDP Application TCP port 80 Transport Network 2019/4/11
Socket API 一個基本Socket程式會用到的Socket APIs listen()、accept() for Server bind() 為新的socket 指定local IP 及Port listen() 使socket 進入等待Client 連接要求狀態 accept() 接受Client連線要求。建立socket 欄位中的remote IP及Port connect() 向Server要求連線 read() 接收對方資料 write() 傳送資料給對方 close() 關閉Socket listen()、accept() for Server connect() for Client 2019/4/11
TCP socket TCP Server TCP Client Socket ( ) Connect ( ) Write ( ) Accept ( ) Read ( ) Listen ( ) Bind ( ) Close ( ) 等待客戶端的連線 建立連線 資料 (請求) 資料 (回應) 處理請求 2019/4/11
creat a socket int socket(int family, int type, int protocol) family AF_INET UNIX network sockets AF_INET6 UNIX network sockets for IPv6 type SOCK_STREAM(TCP) SOCK_DGRAM(UDP) protocol : default 0 return 成功後,函式會傳回0以代表成功,若失敗即傳回-1 2019/4/11
bind() int bind(int socket, const struct socket * address, size_t address_len); socket : return value from socket function *address : struct sockaddr_in 對映於通訊端(socket)所宣告的資料結構 address_len : address length return 成功後,函式會傳回0以代表成功,若失敗即傳回-1。 2019/4/11
bind() (Cont.) bind()的功用是設定了Socket 的本機IP 跟Port 因此需要sockaddr_in* name來設定 struct sockaddr_in{ short sin_family; // 通常是AF_INET u_short sin_port; // Port number struct in_addr sin_addr // IP address char sin_zero[8] // reserved } 2019/4/11
bind() (Cont.) example server_address.sin_family = AF_INET; server_address.sin_addr.s_addr = inet_addr("127.0.0.1"); server_address.sin_port = 9000; server_len = sizeof(server_address); bind(server_sockfd, (struct sockaddr *)&server_address, server_len); 2019/4/11
connect() TCP客戶端使用connect函式來建立與TCP伺服端的連線 Client使用connect()來建立與Server的連線 int connect (int socket, const struct sockaddr *servaddr, soklen_t addrlen) ; 2019/4/11
listen() 建立一個queue以接收其他程式所送達的連線要求(request) int listen(int socket, int backlog) socket : return value from socket function Backlog : Queue length 代表所欲建立的queue大小為多少 成功後,函式會傳回0以代表成功,若失敗即傳回 -1。 2019/4/11
accept() 把Client 的資料跟Server Socket 資料組合成新的Socket int accept (int socket, struct sockaddr *cliaddr, socklen_t *addrlen) ; accept()成功後會傳回一個建立完的Socket 2019/4/11
read() & write() int read(int sockfd, char *buf, int len) socketfd:接收資料之 socket descriptor buf:儲存讀取資料 addrlen:sizeof(buf) 回傳-1 表示錯誤,否則回傳所接收之位元數 int write(int sockfd, char *buf, int len) socketfd:傳送資料之 socket descriptor buf:儲存傳送資料 回傳-1 表示錯誤,否則回傳所傳送之位元數 2019/4/11
close() 用來關閉socket,並且終止TCP連線 int close (int sockfd) ; 2019/4/11
TCP Demo Client : 10.10.59.61 Server : 10.10.59.64 http://ms11.voip.edu.tw/~chenglin/socket_programming socket_tcp_client.c socket_tcp_server.c 2019/4/11
UDP socket (IPv4) UDP伺服端 Socket ( ) 慣用埠 Bind ( ) UDP客戶端 socket ( ) recvfrom ( ) sendto ( ) 暫停直到收到客戶端的資料包 資料 (請求) 處理請求 close ( ) close ( ) 2019/4/11
UDP socket (Cont.) UDP並不會建立與伺服端的連線,而只是使用sendto函式將資料包傳送給伺服端:這函式只需目的位址為參數 而伺服端也不接受來自客戶端的連線,而是呼叫recvfrom函式,等待資料由客戶端送達,並傳回客戶端的協定位址和資料包,使伺服端傳送回應給正確客戶端。 2019/4/11
revfrom() 這兩個函式類似標準的read與write函式 recvfrom (int sockfd, void *buff, size_t nbytes, int flags, struct sockaddr *from, socklen_t *addrlen) ; 前三個參數sockfd、buff、nbytes與read及write的前三個參數相同,分別是描述子、指向讀取或寫入緩衝區的指標以及讀取或寫入的位元組收數目。 recvfrom函式會將傳送端的協定位址填入from所指用的socket位址結構,儲存在該socket位址結構中的位元組數目則會透過addrlen所指向的整數,傳回給呼叫者。 2019/4/11
revfrom() sendto (int sockfd, const void *buff, size_t nbytes, int flags, const struct sockaddr *to, socklen_t addlen) ; sendto 的to參數是socket位址結構,指定資料所要送往的協定位址, addrlen則是指定這個socket位址結構的長度 2019/4/11
UDP Demo Client : 10.10.59.61 Server : 10.10.59.64 socket_tcp_client.c socket_tcp_server.c 2019/4/11
Socket (IPV6) int socket(int family, int type, int protocol) family AF_INET UNIX network sockets AF_INET6 UNIX network sockets for IPv6 Bind() IPv6 address.sin6_family = AF_INET6; address.sin6_addr = in6addr_any; address.sin6_port = 9734; IPv4 server_address.sin_family = AF_INET; server_address.sin_addr.s_addr = inet_addr("127.0.0.1"); server_address.sin_port = 9000; 2019/4/11
TCP demo (IPv6) 2019/4/11