Chương 2
1
LẬP TRÌNH SOCKET
Nội dung
Kiểu dữ liệu và khai báo biến
Các hàm socket
Các hàm hỗ trợ
2
Mô hình kết nối Client/Server
Khai báo socket
#include <sys/socket.h>
int MySock;
………………………………………
structin_addr{
union {
struct { u_char s_b1,s_b2,s_b3,s_b4;} s_un_b;
3
struct { u_char s_b1,s_b2,s_b3,s_b4;} s_un_b;
struct {u_short s_w1,s_s2;}S_un_w;
u_long S_addr;
} S_un;
};
Khai báo địa chỉ socket
struct sockaddr
{
u_sort sa_family;
char sa_data[14];
};
struct sockaddr_in
{
4
{
sa_family_t sin_family;
in_port_t sin_port;
struct in_addr sin_addr;
char sin_zero[8];
};
Khai báo địa chỉ máy
struct hostent
{
char* h_name;
char**
h_alias_name;
5
char**
h_alias_name;
short h_addrtype;
short h_length;
char** h_addr_list;
}
Khai báo địa chỉ dịch vụ
struct servent
{
char* s_name;
6
char** s_aliases;
short s_port;
char s_proto;
}
Khai báo giao thức
struct protoent
{
char* p_name;
7
char** p_aliases;
short p_proto;
}
Network byte order
là sự khác nhau về thứ tự sắp xếp các
byte trong một số interger hoặc
long giữa các hệ điều hành
các hàm chuyển đổi:
8
các hàm chuyển đổi:
short htons(short);
long htonl(long);
short ntohs(short);
long ntohl(long);
Xử lý địa chỉ IP
Chuyển từ dạng chuỗi A.B.C.D sang
địa chỉ dạng số long
long inet_addr(char*);
Chuyển từ địa chỉ dạng số
long
sang
9
Chuyển từ địa chỉ dạng số
long
sang
địa chỉ dạng chuỗi A.B.C.D
char* inet_ntoa(long);
Các hàm socket
Tạo socket
Quản lý kết nối
Gửi nhận dữ liệu
10
Tạo socket
int socket(int af, int type, int protocol);
Tham số
af- họ giao thức, luôn là AF_INET
type – kiểu socket
SOCK_STREAM:
TCP socket
11
SOCK_STREAM:
TCP socket
SOCK_DGRAM: UDP socket
protocol – giao thức sẽ dùng với socket, thường
bằng 0
Giá trị trả về
không lỗi: giá trị miêu tả socket
Lỗi: INVALID_SOCKET
Kết nối socket đến port
int bind(int socket, struct sockaddr
localaddr, int addrlen);
Tham số
socket: chỉ ra socket cần gắn kết đến cổng
12
socket: chỉ ra socket cần gắn kết đến cổng
localaddr: cấu trúc sockaddr với trường sin_port
chỉ ra port cần liên kết đến
addrlen: độ dài của trường localaddr
Giá trị trả về
Nếu có lỗi: SOCKET_ERROR
Kết nối đến quá trình khác
int connect(int socket, struct sockaddr
destaddr, int addrlen);
Thông số
socket: chỉ ra socket nào cần tạo kết nối
13
socket: chỉ ra socket nào cần tạo kết nối
destaddr: cấu trúc sockaddr với sin_addr và
sin_port chỉ ra IP và port
addrlen: độ dài của destaddr
Giá trị trả về
Nếu có lỗi: SOCKET_ERROR
Tạo hàng đợi cho các kết nối đến
int listen(int socket, int
qlength);
Thông số
socket: chỉ ra socket nào cần tạo hàng
14
socket: chỉ ra socket nào cần tạo hàng
đợi
qlength: độ dài của hàng đợi cần tạo
Giá trị trả về
Nếu có lỗi: SOCKET_ERROR
Chấp nhận kết nối đến
int newsock=accept(int mainsock, struct
sockaddr *
fromaddr, int *addrlen);
Thông số
mainsock: socket đang chờ kết nối
fromaddr: địa chỉ của máy gửi yêu cầu kết nối
15
fromaddr: địa chỉ của máy gửi yêu cầu kết nối
đến
addrlen: độ dài của fromaddr
Giá trị trả về
Không lỗi: socket mới, kết nối đến port mới
Có lỗi: INVALID_SOCKET
Gửi dữ liệu qua socket
TCP socket
int send(int socket, char* buffer,int
length,int flags);
UDP socket
16
int sendto(int socket,char* buffer,int
length,int flags, struct sockaddr
desaddr, int addrlen);
Giá trị trả về:
Thành công: số lượng byte dữ liệu thực sự được
gửi
Thất bại: giá trị -1
Gửi dữ liệu qua socket
Thông số
buffer: địa chỉ bắt đầu của chuỗi dữ
liệu cần gửi
length: lượng dữ liệu cần gửi
17
length: lượng dữ liệu cần gửi
flags: các cờ xác định trạng thái gửi
destaddr: địa chỉ (IP,port) của quá trình
nhận
addrlen: độ dài của destaddr
Nhận dữ liệu từ socket
TCP socket
int receive(int socket,char* buffer, int length,
int
flags);
UDP socket
receivefrom
socket
buffer,
18
int
receivefrom
(int
socket
,char*
buffer,
int
length, int flags,struct sockaddr *fromaddr, int
*
addrlen);
Giá trị trả về:
Thành công: số lượng byte dữ liệu thực sự
được nhận
Thất bại: giá trị -1
Nhận dữ liệu từ socket
Thông số
buffer: địa chỉ bắt đầu của chuỗi dữ liệu
cần nhận
length
: lượng dữ liệu lớn nhất có thể
19
length
: lượng dữ liệu lớn nhất có thể
nhận
flags: các cờ xác định trạng thái nhận
fromaddr: địa chỉ (IP,port) của quá trình
nhận
addrlen: độ lớn của fromaddr
Các hàm hỗ trợ (1)
Lấy tên của máy cục bộ
int gethostname(char *name,int *namelen)
Trả về SOCK_ERROR nếu thất bại
Định tên cho máy cục bộ
20
Định tên cho máy cục bộ
int sethostname(char *name,int namelen)
Trả về SOCK_ERROR nếu thất bại
Lấy tên miền cục bộ
int getdomainname(char *name,int namelen)
Trả về SOCK_ERROR nếu thất bại
Các hàm hỗ trợ (2)
Định tên cho miền cục bộ
int setdomainname(char *name,int
namelen)
Trả về SOCK_ERROR nếu thất bại
21
Trả về SOCK_ERROR nếu thất bại
Lấy thông tin của máy đang kết nối
int getpeername(int socket,struct
sockaddr *name,int* namelen)
Trả về SOCK_ERROR nếu thất bại
Các hàm hỗ trợ (3)
Lấy giá trị một option của socket
int getsockopt(int socket, int level,
int optname, char *optval, int
*optlen)
Trả về SOCK_ERROR nếu thất bại
22
Trả về SOCK_ERROR nếu thất bại
Định giá trị của một option của socket
int setsockopt(int socket, int level,
int optname, char *optval, int
*optlen)
Trả về SOCK_ERROR nếu thất bại
Các hàm hỗ trợ (4)
Lấy thông tin máy từ tên máy
struct hostent *gethostbyname(char
*name);
Trả về NULL nếu thất bại
23
Trả về NULL nếu thất bại
Lấy thông tin máy từ địa chỉ máy
struct hostent *gethostbyaddr(char
*addr,int len, int type);
Trả về NULL nếu thất bại
Các hàm hỗ trợ (5)
Lấy thông tin về dịch vụ bằng tên
struct servent *getservbyname(char
*name, char *proto);
Trả về NULL nếu thất bại
24
Trả về NULL nếu thất bại
Lấy thông tin về dịch vụ bằng cổng
struct servent *getservbyport(int
port, char *proto);
Trả về NULL nếu thất bại
Các hàm hỗ trợ (6)
Lấy thông tin về giao thức bằng tên
struct protoent *getprotobyname(char
*name);
Trả về NULL nếu thất bại
25
Trả về NULL nếu thất bại
Lấy thông tin về giao thức bằng số
struct protoent *getprotobynumber(int
number);
Trả về NULL nếu thất bại