Client Active Open send SYNsend SYN,ACK rcv SYN send SYN,ACK rcv RST ESTABLISHED rcv ACK of SYN rcv SYN,ACK send ACK FIN WAIT-1 FIN WAIT-2 CLOSE_WAIT CLOSING rcv ACK send FIN rcv FIN sen
Trang 1L p trình Socket ậ
Giáo viên: Nguyễn Hoài Sơn
Bộ môn Mạng và Truyền thông máy tính Khoa Công nghệ thông tin
Trang 3Giao th c TCP/IP ứ
Modem ATM
FDDI Ethernet
IP Network
Application Layers
Physical Data Link Transport
Trang 4Mô hình khách chủ
1 Client sends request
2 Server handles request
3 Server sends response
Máy chủ quản lý một số tài nguyên
Máy chủ cung cấp dịch vụ cho máy khách dựa trên tài
nguyên quản lý.
Trang 5Client Active Open send SYN
send SYN,ACK
rcv SYN send SYN,ACK
rcv RST
ESTABLISHED
rcv ACK of SYN
rcv SYN,ACK send ACK
FIN WAIT-1
FIN WAIT-2
CLOSE_WAIT CLOSING
rcv ACK
send FIN
rcv FIN send ACK
send FIN
rcv ACK
Tr ng thái k t n i TCP ạ ế ố
Trang 6Giao di n ch ệ ươ ng trình v i giao th c ớ ứ
TCP/IP
Chu n TCP/IP không quy nh giao di n c a ph n m m ng d ng v i ẩ đị ệ ủ ầ ề ứ ụ ớ
ph n mêm th c thi giao th c TCP/IP ầ ự ứ
Việc thực thi giao thức TCP/IP tùy thuộc vào mỗi hệ thống
Giao diện này có thể khác nhau với mỗi hệ điều hành
Giao diện Socket (BSD Unix), mô hình STREAMS (UNIX System V)
Trang 7Các ch c năng c a giao di n ứ ủ ệ
C p phát tài nguyên cho m t cu c truy n tin ấ ộ ộ ề
Xác nh i m cu i c a hai bên truy n tin đị đ ể ố ủ ề
Trang 8Giao di n Socket ệ
Mô hình socket đượ c s d ng r ng rãi hi n nay ử ụ ộ ệ
Cung c p các ch c n ng c b n h tr vi c truy n tin ấ ứ ă ơ ả ỗ ỡ ệ ề trên m ng v i nhi u lo i giao th c ạ ớ ề ạ ứ
Trang 9Socket là gì?
V i OS, socket là i m cu i c a s truy n tin ớ đ ể ố ủ ự ề
Thực thi giao thức TCP/IP
V i m t ng d ng, socket là m t mô t file cho phép các ng d ng ớ ộ ứ ụ ộ ả ứ ụ
c/ghi t m ng
Máy chủ và máy khách liên lạc với nhau bằng cách đọc và viết vào mô tả socket
Sử dụng như các lệnh gọi I/O truyền thống
Các lệnh gọi I/O truyền thống: open, close, read, write, lseek, ioctl
Trang 10C u trúc d li u h th ng cho ấ ữ ệ ệ ố
sockets
a pointer to internal data
structure for file 0
a pointer to internal data
structure for file 1
a pointer to internal data
structure for file 2
a pointer to internal data
structure for file 3
family: AF_INET service: SOCK_STREAM protocol: TCP
Trang 11write() read()
connect()
write()
close()
Connection request
EOF
Wait next request
Process request
read()
data (request)
data (reply)
Trang 12int socket (int family, int type, int protocol);
Returns: non-negative descriptor if OK, -1 on error
Trang 13int sockfd; /* socket descriptor */
if((sockfd = socket ( AF_INET , SOCK_STREAM , 0 )) <
0) {
perror(“socket”);
exit(1);
}
socket trả về giá trị nguyên là một mô tả socket
sockfd < 0 khi có lỗi tạo socket
AF_INET: gán socket với họ giao thức IPv4
SOCK_STREAM: gán kiểu socket là stream
0: sử dụng giao thức mặc định (TCP)
Ví d v t oTCP socket ụ ề ạ
Trang 14bind() : Gán đ a ch cho socket ị ỉ
sockfd = Mô tả file cho socket được tạo ra
sockaddr = Con trỏ trỏ đến cấu trúc địa chỉ socket
addrlen = độ lớn địa chỉ
#include <sys/socket.h>
int bind (int sockfd, const struct sockaddr *sockaddr, socklen_t addrlen); Returns: 0 if OK,-1 on error
Trang 15 Đị a ch socket riêng c a Internet: ỉ ủ
Phải gán (sockaddr_in *) thành (sockaddr *) trong các lệnh gọi connect, bind, and accept
struct sockaddr {
unsigned short sa_family; /* protocol family */
char sa_data[14]; /* address data */
};
struct sockaddr_in {
unsigned short sin_family; /* address family (always AF_INET) */ unsigned short sin_port; /* port num in network byte order */ struct in_addr sin_addr; /* IP addr in network byte order */ unsigned char sin_zero[8]; /* pad to sizeof(struct sockaddr) */
Trang 16int sockfd; /* socket descriptor */
struct sockaddr_in sockaddr; /* used by bind() */
/* create the socket */
bzero(&servaddr, sizeof(servaddr)); /* */
sockaddr.sin_family = AF_INET; /* use the Internet addr family */
sockaddr.sin_port = htons(123); /* bind socket ‘sockfd’ to port 123*/
/* kernel choose IP address bound for the socket */
sockaddr.sin_addr.s_addr = htonl(INADDR_ANY);
if(bind(sockfd, (struct sockaddr*) &sockaddr, sizeof(sockaddr)) < 0) {
perror("bind"); exit(1);
}
Ví d v gán đ a ch socket ụ ề ị ỉ
Trang 17Các hàm chuy n đ i th t Byte ể ổ ứ ự
‘h’ : host byte order ‘n’ : network byte order
‘s’ : short (16bit) ‘l’ : long (32bit)
Trang 18S c n thi t c a vi c chuy n đ i th t ự ầ ế ủ ệ ể ổ ứ ự byte
Trang 19Các hàm x lý buffer ử
#include <strings.h>
void bzero(void *dest, size_t nbytes);
void bcopy(const void *src, void *dest, size_t nbytes);
int bcmp(const void *ptr1, const void *ptr2, size_t nbytes);
Returns: 0 if equal, nonzero if unequal
#include <string.h>
void *memset(void *dest, int c, size_t len);
void *memcpy(void *dest, const void *src, size_t nbytes);
int memcmp(const void *ptr1, const void *ptr2, size_t nbytes);
Returns: 0 if equal, <0 or >0 if unequal
Trang 20listen() : Ch đ nh socket l ng nghe k t ỉ ị ắ ế
n i ố
sockfd = Mô tả file của socket đã tạo
backlog = Số lượng tối đa của các kết nối đang chờ
#include <sys/socket.h>
int listen (int sockfd, int backlog);
Returns: 0 if OK, -1 on error
Trang 21Ví d s d ng hàm listen() ụ ử ụ
struct sockaddr_in sockaddr; /* used by bind()
*/
/* 1) create the socket */
/* 2) bind the socket to a port */
if(listen(sockfd, 5) < 0) {
perror(“listen”);
exit(1);
}
Trang 22accept (): Ch k t n i đ n ờ ế ố ế
sockfd = Mô t file c a socket ch ả ủ ờ
cliaddr = Con tr t i c u trúc a ch socket c a ti n trình k t n i ỏ ớ ấ đị ỉ ủ ế ế ố đế n
int accept (int sockfd, struct sockaddr *cliaddr, socklen_t *addrlen);
Returns: non-negative descriptor if OK, -1 on error
Trang 23accept() (2)
Three way handshake completeTCP
Server
accept
Completed connection queue
Incompleteconnection queue
Trang 24Ví d v hàm accept () ụ ề
/* 1) create the socket */
/* 2) bind the socket to a port */
/* 3) listen on the socket */
newfd = accept(sockfd, (struct sockaddr*) &cliaddr, &cliaddr_len); if(newfd < 0) {
perror("accept"); exit(1);
}
Máy chủ biết thông tin máy khách bằng cách nào?
cliaddr.sin_addr.s_addr chỉ định địa chỉ IP của máy khách
cliaddr.sin_port chỉ định cổng của máy khách
Trang 25connect(): Thi t l p m t k t n i v i máy ế ậ ộ ế ố ớ
ch TCP ủ
sockfd = Mô t file c a socket ã t o ra ả ủ đ ạ
servaddr = Con tr t i c u trúc a ch socket c a máy ch k t ỏ ớ ấ đị ỉ ủ ủ ế
Trang 26#include <arpa/inet.h>
int inet_aton(const char *strptr, struct in_addr *addrptr);
Returns: 1 if string was valid, 0 on errorin_addr_t inet_addr(const char *strptr);
Returns: 32-bit binary network byte ordered IPv4
address;
INADDR_NONE if error
Chuyển đổi địa chỉ dạng số thành chuỗi ký tự:
Làm vi c v i đ a ch IP ệ ớ ị ỉ
char *inet_ntoa(struct in_addr inaddr);
Chuyển đổi chuỗi ký tự thành địa chỉ dạng số:
Đị a ch IP th ỉ ườ ng đượ c vi t b i chu i ký t (“128.2.35.50”), nh ng trong ch ế ở ỗ ự ư ươ ng trình a ch IP đị ỉ đượ c bi u di n b ng chu i ký t bit ể ễ ằ ỗ ụ
Trang 27 len = kích thước buffer chuõi ký tự địa chỉ
INET_ADDRSTRLEN for IPv4
#include <arpa/inet.h>
int inet_pton (int family, const char *strptr, void *addrptr);
Returns: 1 if OK, 0 if input not a valid presentation format, -1 on error
const char *inet_ntop (int family, const void *addrptr, char *strptr, size_t len);
Returns: pointer to result if OK, NULL on error
Trang 28M t ví d v connect() ộ ụ ề
connect cho phép m t máy khách k t n i v i máy ch … ộ ế ố ớ ủ
/* create the socket */
/* connect: use the Internet address family */
Trang 29Client Active Open connect() send SYN
send SYN,ACK
rcv SYN send SYN,ACK
rcv RST
ESTABLISHED
rcv ACK of SYN
rcv SYN,ACK send ACK
FIN WAIT-1
FIN WAIT-2
CLOSE_WAIT CLOSING
rcv ACK
Close() send FIN
rcv FIN send ACK
Close() send FIN
rcv ACK
Close()
Các tr ng thái k t n i TCP ạ ế ố
Trang 30Socket I/O: read()
/* 1) create the socket */
/* 2) bind the socket to a port */
/* 3) listen on the socket */
/* 4) accept the incoming connection */
if((nbytes = read(newfd, buf, sizeof(buf))) < 0) {
perror(“read”); exit(1);
read có th s d ng v i socket ể ử ụ ớ
read blocks đợ ữ ệ ừ i d li u t máy khách Hàm read không đả m b o kích th ả ướ c d ữ
li u ệ đọ đượ ằ c c b ng kích th ướ c d li u ch nh sizeof(buf) ữ ệ ỉ đị
Trang 31Socket I/O: write()
L nh ệ write có th dùng v i m t socket ể ớ ộ
struct sockaddr_in srv; /* used by connect() */
/* 1) create the socket */
/* 2) connect() to the server */
/* Example: A client could “write” a request to a server
Trang 32fgets
fputs Usage:
%server <listen port>
%client <server’s IP address> <server’s listen port number>
Trang 33Ch ươ ng trình máy ch ủ Echo
tcpserv01.c
Trang 34Ch ươ ng trình máy khách Echo
tcpcli01.c
Trang 35Review: TCP Client-Server
Interaction
socket()bind()listen()accept()
write()read()
read()close()
connection establishment data request
data reply end-of-file notification
Trang 36Datagram (UDP) Client/Server
close() sendto()
recvfrom() sendto()
recvfrom() close()
Client
data (request)data (reply)
socket() bind() socket()
Trang 37recvfrom() and sento()
sockfd = Mô tả file của socket
buff = Con trỏ trỏ đến buffer để nhận/gửi dữ liệu
nbytes = Số lượng byte nhận/gửi
flags = dùng với các hàm xuất nhập I/O (mặc định là 0)
from = Con trỏ trỏ đến cấu trúc địa chỉ socket chứa thông tin của bên gửi gói tin
to = Con trỏ trỏ đến cấu trúc địa chỉ socket chứa thông tin của bên nhận gói tin
addrlen = kích thước của cấu trúc địa chỉ socket
#include <sys/socket.h>
ssize_t recvfrom(int sockfd, void *buff, size_t nbytes, int flags,
struct sockaddr *from, socklen_t *addrlen); ssize_t sendto(int sockfd, const void *buff, size_t nbytes, int flags,
const struct sockaddr *to, socklen_t addrlen); Both return: number of bytes read or written if OK, –1 on error
Trang 38IP
Ethernet Adapter
NTPdaemon
Port 123
Máy ch cung c p th i gian m ng NTP ủ ấ ờ ạ
Máy ch ủ UDP c n làm gì ầ để máy khách UDP có th k t n i ể ế ố đế n?
Trang 39Socket I/O: socket()
Máy ch UDP ph i t o socket ủ ả ạ datagram …
if((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
Trang 40Socket I/O: bind()
Gán c ng cho ổ socket …
struct sockaddr_in servaddr; /* used by bind() */
/* create the socket */
/* bind: socket ‘fd’ to port 80*/
/* bind: a client may connect to any of my addresses */
perror("bind"); exit(1);
}
Trang 41Socket I/O: recvfrom()
struct sockaddr_in servaddr; /* used by bind() */
struct sockaddr_in cliaddr; /* used by recvfrom() */
int cliaddr_len = sizeof(cliaddr); //used by recvfrom()
/* 1) create the socket */
/* 2) bind to the socket */
nbytes = recvfrom(fd, buf, sizeof(buf), 0 /* flags */,
(struct sockaddr*) &cliaddr, &cliaddr_len);
if(nbytes < 0) {
perror(“recvfrom”); exit(1);
Trang 42Socket I/O: recvfrom() continued
nbytes = recvfrom(fd, buf, sizeof(buf), 0 /* flags */,
(struct sockaddr*) cli, &cli_len);
copy nbytes dữ liệu vào buf
Trang 43 Làm th nào ế để ộ m t máy khách UDP
liên l c v i máy ch ạ ớ ủ UDP?
Trang 44Socket I/O: sendto()
Không s d ng l nh write ử ụ ệ
Máy khách UDP không gán s hi u c ng c a máy ch cho socket ố ệ ổ ủ ủ
Số hiệu cổng được gán động khi lệnh sendto được gọi lần đầu tiên
/* 1) create the socket */
/* sendto: send data to IP Address “198.0.0.50” port 123 */
srv.sin_family = AF_INET;
srv.sin_port = htons(123);
srv.sin_addr.s_addr = inet_addr(“198.0.0.50”);
nbytes = sendto(fd, buf, sizeof(buf), 0 /* flags */,
(struct sockaddr*) &srv, sizeof(srv));
if(nbytes < 0) {
Trang 45Review: UDP Client-Server Interaction
socket()bind()recvfrom()
blocks until datagram received from a client data request
data reply
Trang 46Chuy n đ i tên mi n thành đ a ch ể ổ ề ị ỉ
IP
gethostbyname cung c p giao diên ấ đế n h th ng tên mi n DNS ệ ố ề
struct hostent *gethostbyname (const char *hostname);
struct hostent {
char *h_name; /* Tên miền chính thức */
char **h_aliases; /* Con trỏ trỏ tới chuỗi con trỏ tên miền alias */
int h_addrtype; /* Họ giao thức: AF_INET */
int h_length; /* Kích thước địa chỉ: 4 */
char **h_addr_list; /* Con trỏ trỏ tới chuỗi con trỏ địa chỉ IPv4*/
};
#include <netdb.h>
struct hostent *hp;
struct sockaddr_in peeraddr;
char *name = “www.vnu.edu.vn”;
peeraddr.sin_family = AF_INET;
Trang 47M t s hàm khác ộ ố
gethostbyaddr
struct hostent *gethostbyaddr (const char *addr, socklen_t len, int family);
addr: Con trỏ trỏ tới cấu trúc in_addr chứa địa chỉ IPv4
trả về con trỏ trỏ tới cấu trúc hostent với tên miền tương ứng
char *s_name; /* official service name */
char **s_aliases; /* alias list */
int s-port; /* port number, network-byte order */
char *s_proto; /* protocol to use */
};
Trang 48Bài t p 1 ậ