You are on page 1of 48

om

.c
Socket Programming

ng
co
an
th
o ng
du
u
cu

TS. Trần Quang Vinh


BM. Kỹ thuật Thông tin
Viện Điện tử - Viễn thông
Đại học Bách Khoa Hà Nội
m706501@shibaura-it.ac.jp

CuuDuongThanCong.com https://fb.com/tailieudientucntt
Socket là gì?

Socket là một cổng logic mà một chương trình sử dụng để kết nối

om
với một chương trình khác chạy trên một máy tính khác trên Internet

.c
Server thì sẽ cần một socket để lắng nghe các kết nối từ Client
Client thì phải cần có một socket để kết nối tới Sever

ng
Chương trình mạng có thể sử dụng nhiều Socket cùng một lúc, nhờ

co
đó nhiều ứng dụng có thể sử dụng Internet cùng một lúc.

an
Socket Interface được định nghĩa trong UNIX BSD, dựa trên việc

th
mở rộng tập các system calls (access files)
ng
Hiện có nhiều platform khác nhau cung cấp API cho các ứng dụng
o
mạng, có sự khác biệt nhỏ giữa các thư viện socket trên các platform
du

khác nhau
u

Việc lập trình ứng dụng sử dụng socket sẽ dựa vào 1 trong 2 giao
cu

thức TCP hoặc UDP của lớp giao vận

CuuDuongThanCong.com https://fb.com/tailieudientucntt
Mô hình hoạt động client/server dùng socket

Hai ứng dụng client/server lúc còn độc lập nhau

om
.c
ng
co
an
Hai ứng dụng client/server lúc giao tiếp nhau (dùng kết nối TCP và

th
giao thức request/reply) ng
o
du
u
cu

CuuDuongThanCong.com https://fb.com/tailieudientucntt
Cấu trúc địa chỉ Internet

Định nghĩa dạng dữ liệu cấu trúc trong ngôn ngữ C. Cấu trúc này

om
chỉ có 1 trường kiểu u_long chứa địa chỉ IP 32 bit

.c
ng
co
an
th
o ng
du
u
cu

CuuDuongThanCong.com https://fb.com/tailieudientucntt
Cấu trúc địa chỉ Socket

Cấu trúc địa chỉ socket sockaddr_in lưu trữ địa chỉ IP, chỉ số port,

om
và kiểu (family protocol)

.c
ng
co
an
th
o ng
du

sin_len: lưu trữ chiều dài cấu trúc của sockaddr_in


sin_family: dạng protocol của socket
u
cu

sin_port: chỉ số port


sin_addr: địa chỉ in Internet của socket
sin_zero[8]: không dùng, đặt giá trị = 0

CuuDuongThanCong.com https://fb.com/tailieudientucntt
Cấu trúc socket

Socket được định nghĩa trong hệ điều hành bằng một cấu trúc,

om
được xem như điểm nối để hai procceses giao tiếp với nhau

.c
Cấu trúc socket gồm 5 field:

ng
Family: xác định protocol group

co
Type: xác loại socket, stream, datagram hay raw socket.
Protocol: là field thường gán giá trị bằng 0

an
Local Socket Address và Remote Socket Address: là địa chỉ socket của

th
process cục bộ và từ xa
o ng
du
u
cu

CuuDuongThanCong.com https://fb.com/tailieudientucntt
Các loại socket

Các giao tiếp socket được định nghĩa trên môi trường TCP/IP

om
Stream Socket: dùng cho connection-oriented protocol (TCP)

.c
Datagram Socket: dùng cho connectionless protocol (UDP)

ng
Raw Socket: dùng cho một số protocol của một số ứng dụng đặc biệt,
dùng các dịch vụ trực tiếp của lớp IP

co
an
th
o ng
du
u
cu

CuuDuongThanCong.com https://fb.com/tailieudientucntt
Byte Ordering

Big-Endian Byte Order:

om
Byte có trọng số lớn lưu trước (Most Significant byte first)

.c
ng
co
an
th
ng
Little-Endian Byte Order:
o
du

Byte có trọng số nhỏ lưu trước (Lest Significant byte first)


u
cu

CuuDuongThanCong.com https://fb.com/tailieudientucntt
Byte Ordering

Network Byte Order:

om
Thứ tự lưu trữ dùng cho giao tiếp mạng

.c
Tuỳ cấu trúc của mỗi host, lưu trữ số theo một trong hai cách trên 
không đồng nhất khi thực hiện giao tiếp trên network

ng
Giao tiếp socket định nghĩa một số hàm để thực hiện các thao tác

co
chuyển đổi:

an
 htons() và htonl(): chuyển từ dạng lưu trữ của host sang network

th
 ntohs() và ntohl(): chuyển từ dạng lưu trữ của network sang host
ng
o
du
u
cu

CuuDuongThanCong.com https://fb.com/tailieudientucntt
inet_ntoa(), inet_aton()

char *inet_ntoa(struct in_addr in);

om
int inet_aton(const char *cp, struct in_addr *inp);

.c
Chuyển đổi địa chỉ IP từ dạng chuỗi “thập phân với dấu chấm” sang

ng
dạng cấu trúc in_addr và ngược lại

co
inet_aton() returns non-zero if the address is a valid one, and it returns
zero if the address is invalid

an
inet_ntoa() returns the dots-and-numbers string in a static buffer that is

th
overwritten with each call to the function
ng
 The “n” in “ntoa” stands for network, and the “a” stands for ASCII, so it's
o
“Network To ASCII”
du
u
cu

10

CuuDuongThanCong.com https://fb.com/tailieudientucntt
Các hàm cơ bản dùng cho lập trình socket

socket()

om
bind()

.c
connect()

ng
listen()

co
accept()

an
read() / write()

th
send() / recv()
ng
sendto() / recvfrom()
o
du

close() / shutdown()
u
cu

11

CuuDuongThanCong.com https://fb.com/tailieudientucntt
Hàm socket()

#include <sys/types.h>

om
#include <sys/socket.h>

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

ng
Hàm socket() tạo một socket, kết quả trả về là một số nguyên nhận

co
dạng (socket descriptor), nếu có lỗi giá trị trả về là -1

an
Các tham số:

th
domain: họ socket ng
type: kiểu socket
o
protocol: giao thức, thường đặt bằng 0
du
u
cu

12

CuuDuongThanCong.com https://fb.com/tailieudientucntt
Hàm socket()

om
.c
ng
co
an
th
o ng
du
u
cu

13

CuuDuongThanCong.com https://fb.com/tailieudientucntt
Hàm socket()

Ví dụ

om
// Khởi tạo socket mới, nếu thất bại báo sai

.c
#include <sys/types.h>

ng
#include <sys/socket.h>
int main(void)

co
{
int sockfd;

an
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{

th
perror("socket"); ng
exit(1);
}
o
printf("Sockfd : %d \n", sockfd);
du

}
u
cu

14

CuuDuongThanCong.com https://fb.com/tailieudientucntt
Hàm bind()

#include <sys/types.h>

om
#include <sys/socket.h>

.c
int bind(int sockfd, struct sockaddr *my_addr, int addrlen);

ng
Chức năng:

co
Đăng ký socket đã khởi tạo với địa chỉ socket local

an
Trả về 0 nếu thành công, -1 nếu thất bại

th
Các tham số: ng
sockfd: mô tả socket trả về bởi hàm socket()
o
my_addr: con trỏ chỉ đến struct sockaddr của địa chỉ socket bao gồm
du

cổng và IP address
u

addrlen: chiều dài (byte) của địa chỉ socket


cu

15

CuuDuongThanCong.com https://fb.com/tailieudientucntt
Hàm connect()

#include <sys/types.h>

om
#include <sys/socket.h>

.c
int connect(int sockfd, struct sockaddr *serv_addr, int addrlen);

ng
Chức năng

co
Dùng cho chương trình client thiết lập kết nối đến server

an
Trả về 0 nếu thành công, -1 nếu thất bại

th
Các tham số: ng
sockfd: mô tả socket được trả về bởi hàm socket()
o
serv_addr: con trỏ địa chỉ socket của server
du

addrlen: chiều dài của địa chỉ socket server


u
cu

16

CuuDuongThanCong.com https://fb.com/tailieudientucntt
Hàm listen()

int listen(int sockfd, int backlog);

om
.c
Chức năng:

ng
Hàm listen() để kết nối đến server, khai báo độ dài hàng chờ

co
Hàm này dùng cho chương trình server connection-oriented để đặt
socket ở trạng thái chờ, lắng nghe kết nối từ phía client

an
Trả về 0 nếu thành công, -1 nếu thất bại
Các tham số:
th
ng
sockfd: mô tả socket đã tạo bởi hàm socket()
o

du

backlog: số request có thể queued (giới hạn bởi 20, thường từ 5-10)
u
cu

17

CuuDuongThanCong.com https://fb.com/tailieudientucntt
Hàm accept()

#include <sys/types.h>

om
#include <sys/socket.h>

.c
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

ng
Chức năng

co
Chấp nhận kết nối từ client, tạo socket mới

an
Giá trị là một socket descriptor của socket mới

th
Returns: non-negative descriptor if OK, -1 on error
ng
Các tham số:
o
sockfd: mô tả socket đã tạo bởi hàm socket()
du

addr: con trỏ địa chỉ socket của client kết nối đến
u
cu

addrlen: chiều dài của addr

18

CuuDuongThanCong.com https://fb.com/tailieudientucntt
Các hàm trao đổi dữ liệu

Gửi/Nhận dữ liệu trên giao thức TCP (stream sockets or connected

om
datagram sockets)

.c
send() / recv()
write() / read()

ng
Gửi/Nhận dữ liệu trên giao thức UDP (regular unconnected

co
datagram sockets)

an
sendto() / recvfrom()

th
o ng
du
u
cu

19

CuuDuongThanCong.com https://fb.com/tailieudientucntt
Hàm send()

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

om
.c
Chức năng

ng
Gửi dữ liệu tới một socket

co
Trả về số bytes được gửi thành công, trả về -1 nếu thất bại

an
 Số bytes được gửi thành công có thể nhỏ hơn số bytes thực sự muốn gửi

th
Các tham số: ng
sockfd: mô tả socket muốn gửi dữ liệu đến, đây có thể là giá trị trả về
bởi hàm socket() hoặc accept()
o
du

msg: con trỏ đến dữ liệu muốn gửi


u

len: chiều dài của dữ liệu (in byte)


cu

flags: tập các cờ điều khiển hoạt động của hàm này, thường set giá trị 0

20

CuuDuongThanCong.com https://fb.com/tailieudientucntt
Hàm recv()

int recv(int sockfd, void *buf, int len, int flags);

om
.c
Chức năng

ng
Nhận dữ liệu từ một socket

co
Trả về số bytes nhận được, trả về -1 nếu thất bại

an
 Số bytes nhận được có thể nhỏ hơn số bytes yêu cầu bởi tham số len

th
Các tham số: ng
sockfd: mô tả socket muốn nhận dữ liệu
o
buf: con trỏ đến bộ đệm muốn lưu dữ liệu
du

len: chiều dài tối đa của bộ đệm (in byte)


u

flags: tập các cờ điều khiển hoạt động của hàm này, thường set giá trị 0
cu

21

CuuDuongThanCong.com https://fb.com/tailieudientucntt
Hàm read()

int read(int sockfd, const void *buf, int len);

om
.c
Chức năng

ng
Đọc dữ liệu từ connection vào bộ nhớ

co
Trả về số bytes đọc được nếu thành công, trả về 0 nếu không có dữ
liệu, trả về -1 nếu thất bại

an
Các tham số:

th
ng
sockfd: mô tả socket đã tạo bởi hàm socket()
buf: con trỏ đến bộ đệm để lưu thông tin đọc được
o

du

len: chiều dài của bộ đệm


u
cu

22

CuuDuongThanCong.com https://fb.com/tailieudientucntt
Hàm write()

int write(int sockfd, const void *buf, int len);

om
.c
Chức năng

ng
Ghi dữ liệu từ bộ nhớ lên connection.

co
Trả về số bytes ghi được nếu thành công, trả về -1 nếu thất bại

an
Các tham số:

th
sockfd: mô tả socket đã tạo bởi hàm socket()
ng
buf: con trỏ đến bộ đệm để lưu thông tin đọc được
o
len: chiều dài của bộ đệm
du
u
cu

23

CuuDuongThanCong.com https://fb.com/tailieudientucntt
Hàm sendto()

int sendto (int sockfd,

om
const void *buf,
int len,

.c
int flags,
const struct sockaddr_in *toaddr,

ng
int toaddrlen);

co
an
Chức năng:

th
Gửi dữ liệu đến một địa chỉ socket từ xa
ng
Trả về số bytes gửi được nếu thành công, trả về -1 nếu thất bại
o
du

Các tham số:


sockfd, buf, len: giống các hàm đã giới thiệu
u
cu

flags: thường đặt bằng 0


toaddr, toaddrlen: địa chỉ socket đến và chiều dài của nó

24

CuuDuongThanCong.com https://fb.com/tailieudientucntt
Hàm recvfrom()

int recvfrom ( int sockfd,

om
const void *buf,
int len,

.c
int flags,
const struct sockaddr_in *fromaddr,

ng
int fromaddrlen);

co
an
Chức năng

th
Nhận dữ liệu từ một địa chỉ socket từ xa
ng
Trả về số bytes gửi được nếu thành công, trả về -1 nếu thất bại
o
du

Các tham số:


sockfd, buf, len: giống các hàm đã giới thiệu
u
cu

flags: thường đặt bằng 0


fromaddr, fromaddrlen: địa chỉ socket gửi đến và chiều dài của nó

25

CuuDuongThanCong.com https://fb.com/tailieudientucntt
Hàm fork() – Khởi tạo process

#include <unistd.h>

om
pid_t fork(void);

.c
ng
Chức năng

co
Khởi tạo các process, sử dụng trong multi-threading

an
Không có tham số

th
Nếu khởi tạo thành công, trả về hai giá trị: (-1 nếu lỗi)
ng
 Trả về process ID của child’s process cho parent’s process
o
 Trả về 0 cho child’s process
du

type pid_t defined in sys/types.h. Normally, the process ID is an


u

integer
cu

26

CuuDuongThanCong.com https://fb.com/tailieudientucntt
Hàm close() / shutdown()

#include <unistd.h>

om
int close(int sockfd);

.c
#include <sys/socket.h>
int shutdown(int sockfd, int how);

ng
co
Chức năng

an
Hàm close() đóng một socket cả phía client và server, đồng thời giải

th
phóng socket ng
Hàm shutdown() đóng một phía client hoặc server, không giải phóng
socket, vẫn phải gọi hàm close() khi muốn thực sự ngắt kết nối
o
du

 Tham số how
u
cu

Trả về 0 nếu thành công và -1 nếu thất bại


Trên windows platfrom gọi hàm closesocket()

27

CuuDuongThanCong.com https://fb.com/tailieudientucntt
Hàm thiết lập bộ nhớ - memset()

void* memset( void* buffer, int ch, size_t count );

om
Chức năng

.c
Khởi tạo vùng bộ nhớ chỉ ra bởi con trỏ buffer, điền đầy count bytes
đầu tiên của vùng bộ nhớ này bởi ch

ng
Trả về con trỏ chỉ tới vùng bộ nhớ buffer

co
#include <stdio.h>

an
#include <string.h>

th
#define LENGTH 10
ng
int main(void)
{
o
char x='X';
du

char buffer[LENGTH];
int cnt=0;
u
cu

memset(buffer,x,LENGTH);
for(;cnt < LENGTH; cnt++) {
printf("\nbuffer[%d] = %c",cnt,buffer[cnt]);
}

28

CuuDuongThanCong.com https://fb.com/tailieudientucntt
Hàm so sánh memcmp()

int memcmp(const void *buffer1,

om
const void *buffer2, size_t count);

.c
Chức năng

ng
So sánh 'count' kí tự đầu tiên của 2 chuỗi buffer1 và buffer2

co
Giá trị trả về:

an
< 0: buffer1 < buffer2

th
= 0: buffer1=buffer2
> 0: buffer1 > buffer2
o ng
du
u
cu

29

CuuDuongThanCong.com https://fb.com/tailieudientucntt
Hàm copy bộ nhớ memcpy()

void *memcpy( void *to, const void *from, size_t count );

om
Chức năng

.c
Copy count kí tự từ from sang to

ng
Giá trị trả về là to

co
 hàm này sẽ copy nguyên chính xác số bytes cần copy và không copy bytes
cuối cùng của string '\0'. Vì vậy cần phải copy n+1 nếu muốn copy n byte

an
#include <stdio.h>

th
#include <string.h> ng
int main(void)
{
o
const char from[]="Xcross87 is a chick of programming";
du

char* to;
u

memcpy(to,from,strlen(from)+1);
cu

printf(" Gia tri cua \'to\' sau khi copy la: %s ",to);

return 0;
}
30

CuuDuongThanCong.com https://fb.com/tailieudientucntt
getaddrinfo(), freeaddrinfo(), gai_strerror()

om
.c
ng
co
an
th
Chức năng
ng
getaddrinfo() lấy thông tin về host name, service, và khởi tạo sockaddr
o
bằng kết quả trả về
du

Trả về 0 nếu thành công, khác 0 nếu có lỗi, bắt lỗi bằng hàm
u

gai_strerror()
cu

freeaddrinfo() giải phóng bộ nhớ

31

CuuDuongThanCong.com https://fb.com/tailieudientucntt
Giải thuật cho TCP client

Xác định địa chỉ server

om
Tạo socket

.c
Kết nối đến server

ng
Gởi/nhận dữ liệu theo giao thức lớp ứng dụng đã thiết kế

co
Đóng kết nối

an
th
o ng
du
u
cu

32

CuuDuongThanCong.com https://fb.com/tailieudientucntt
Giải thuật cho UDP client

Xác định địa chỉ server

om
Tạo socket

.c
Đăng ký socket với hệ thống

ng
Gởi/nhận dữ liệu theo giao thức lớp ứng dụng đã thiết kế đến server

co
theo địa chỉ đã xác định

an
Đóng kết nối

th
o ng
du
u
cu

33

CuuDuongThanCong.com https://fb.com/tailieudientucntt
Giải thuật cho iterative server

Connection-oriented iterative server:

om
Tạo socket

.c
Đăng ký địa chỉ socket với hệ thống

ng
Đặt socket ở trạng thái lắng nghe, chờ và sẵn sàng cho việc kết nối từ
client

co
Chấp nhận kết nối từ client, gửi/nhận dữ liệu theo giao thức lớp ứng

an
dụng đã thiết kế

th
Đóng kết nối sau khi hoàn thành, trở lại trạng thái lắng nghe và chờ kết
ng
nối mới
o
Connectionless iterative server:
du

Tạo socket
u

Đăng ký với hệ thống


cu

Lặp công việc đọc dữ liệu từ client gửi đến, xử lý và gửi trả kết quả cho
client theo đúng giao thức lớp ứng dụng đã thiết kế

34

CuuDuongThanCong.com https://fb.com/tailieudientucntt
Connection-oriented iterative server

om
.c
ng
co
an
th
o ng
du
u
cu

35

CuuDuongThanCong.com https://fb.com/tailieudientucntt
Connectionless iterative server

om
.c
ng
co
an
th
o ng
du
u
cu

36

CuuDuongThanCong.com https://fb.com/tailieudientucntt
Connectionless iterative server

om
.c
ng
co
an
th
o ng
du
u
cu

37

CuuDuongThanCong.com https://fb.com/tailieudientucntt
Concurrent Server

Các yêu cầu cho concurrent Server:

om
Tại một thời điểm có thể xử lý nhiều yêu cầu từ client

.c
Chương trình concurrent server có thể chạy trên máy chỉ có 1 CPU

ng
Hệ thống phải hỗ trợ multi-tasking

co
an
th
o ng
du
u
cu

38

CuuDuongThanCong.com https://fb.com/tailieudientucntt
Concurrent Server

Giải thuật cho chương trình

om
connection-oriented concurrent
server:

.c
Tạo socket, đăng ký với hệ thống

ng
Đặt socket ở chế độ chờ, lắng

co
nghe kết nối

an
Khi có request từ client, chấp nhận

th
kết nối, tạo một process con để xử
lý. Quay lại trạng thái chờ, lắng
ng
nghe kết nối mới
o
du

Công việc của process mới gồm:


 Nhận thông tin kết nối của client
u
cu

 Giao tiếp với client theo giao thức


lớp ứng dụng đã thiết kế
 Đóng kết nối và kết thúc process
con

39

CuuDuongThanCong.com https://fb.com/tailieudientucntt
Connection-oriented concurrent server

om
.c
ng
co
an
th
o ng
du
u
cu

40

CuuDuongThanCong.com https://fb.com/tailieudientucntt
Connection-oriented concurrent server

om
.c
ng
co
an
th
o ng
du
u
cu

41

CuuDuongThanCong.com https://fb.com/tailieudientucntt
Concurrent Server

Giải thuật cho chương trình concurrent, connectionless server:

om
Tạo socket, đăng ký với hệ thống

.c
Lặp việc nhận dữ liệu từ client, đối với một dữ liệu nhận, tạo mới một
process để xử lý. Tiếp tục nhận dữ liệu mới từ client

ng
Công việc của process mới:

co
 Nhận thông tin của process cha chuyển đến, lấy thông tin socket

an
 Xử lý và gửi thông tin về cho client theo giao thức lớp ứng dụng đã thiết kế

th
 Kết thúc ng
o
du
u
cu

42

CuuDuongThanCong.com https://fb.com/tailieudientucntt
Multi-protocol Server (TCP,UDP)

Dùng một chương trình để mở một master socket cho cả TCP và

om
UDP

.c
Dùng hàm hệ thống (select) để chọn lựa TCP socket hay UDP
socket sẵn sàng

ng
Tùy vào protocol (TCP, UDP) để xử lý gửi nhận thông điệp theo

co
đúng giao thức của lớp ứng dụng

an
Tham khảo thêm RFC 1060

th
o ng
du
u
cu

43

CuuDuongThanCong.com https://fb.com/tailieudientucntt
Multi-service Server

Tạo một điểm giao tiếp chung

om
Với mỗi request, xem loại dịch vụ cần xử lý

.c
Với mỗi loại dịch vụ, xử lý riêng biệt

ng
Có thể kết hợp Multi-service và Multi- protocol để thiết kế cho

co
chương trình server

an
th
o ng
du
u
cu

44

CuuDuongThanCong.com https://fb.com/tailieudientucntt
SOME SUMMARY

om
.c
ng
co
an
th
o ng
du
u
cu

45

CuuDuongThanCong.com https://fb.com/tailieudientucntt
SOME SUMMARY

om
.c
ng
co
an
th
o ng
du
u
cu

46

CuuDuongThanCong.com https://fb.com/tailieudientucntt
SOME SUMMARY

om
.c
ng
co
an
th
o ng
du
u
cu

47

CuuDuongThanCong.com https://fb.com/tailieudientucntt
SOME SUMMARY

om
.c
ng
co
an
th
o ng
du
u
cu

48

CuuDuongThanCong.com https://fb.com/tailieudientucntt

You might also like