- Là mô hình phổ biến cho giao tiếp giữa 2 tiến trình/2 máy, trong đó, tiến trình client kết nối đến tiến trình server để yêu cầu trao đổi dữ liệu. - Client cần biết về sự tồn tại và địa chỉ của tiến trình server, nhưng server không cần biết về sự tồn tại và địa chỉ của client cho đến khi kết nối - Mỗi khi kết nối được thiết lập, cả 2 bên đều có thể trao đổi (gửi và nhận dữ liệu). - Để thiết lập một kết nối cho cả 2 phía, cần xây dựng một socket. Có thể hiểu socket như một điểm đầu cuối của kênh kết nối giữa 2 tiến trình. (Giống như là thực hiện một kết nối giữa 2 người trong một cuộc gọi điện thoại) - Các hệ thống (linux, windows) đều cung cấp các hàm hệ thống để thực hiện thiết lập một socket. 2. Các loại socket Có 2 loại socket được sử dụng rộng rãi là: stream sockets và datagram sockets. - Stream sockets: Dựa trên giao thức TCP (Tranmission Control Protocol), là giao thức hướng luồng (stream oriented). Việc truyền dữ liệu chỉ - Datagram sockets: Dựa trên giao thức UDP (User Datagram Protocol), là giao thức hướng thông điệp (message oriented). Việc truyền dữ 3. Minh họa lập trình socket Bài viết này minh họa lập trình socket trên linux sử dụng trực tiếp các hàm socket api bằng ngôn ngữ C. - Các bước thiết lập một socket phía client gồm: + Tạo một socket bằng hàm socket() + Kết nối socket đến địa chỉ của server bằng hàm connect() + Gửi và nhận dữ liệu: Có một số cách khác nhau, đơn giản nhất là sử dụng các hàm read() và write() - Các bước thiết lập một socket phía server gồm: + Tạo một socket bằng hàm socket() + Gắn (bind) socket đến địa chỉ của server sử dụng hàm bind(). Đối với server trên internet địa chỉ bao gồm địa chỉ ip của máy host + số hiệu cổng dịch vụ (port number) + Lắng nghe (listen) các kết nối đến từ clients sử dụng hàm listen() + Chấp nhận các kết nối sử dụng hàm accept(). Hàm này sẽ dừng (block) cho đến khi nhận được một client kết nối đến. + Gửi và nhận dữ liệu với client (hàm read(), write()) server.c client.c Biên dịch và chạy 2 chương trình này (trên cùng một máy local host, hoặc 2 máy riêng biệt kết nối mạng) - Với server: server portnumber - Với client: client server_address portnumber Client kết nối và gửi một thông điệp đến server, server nhận và trả lời. Phần tiếp theo giải thích chi tiết mã nguồn 3.1. Chương trình server.c |
/* A simple server in the internet domain using TCP
The port number is passed as an argument */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h> //Thư viện chứa các cấu trúc cần thiết cho socket
#include <netinet/in.h> //Thư viện chứa các hằng số, cấu trúc khi sử dụng địa chỉ trên internet
#include <errno.h>
int main(int argc, char *argv[])
{
int sockfd; //socket server tạo ra để nghe kết nối
int newsockfd; //socket tạo ra khi server chấp nhận một kết nối từ client
int portno; //So hieu cong dich vu
char sendbuff[256]; //buffer to send data
char recvbuff[256]; //buffer to read data
struct sockaddr_in serv_addr, client_addr; //Cấu trúc chứa thông tin địa chỉ server, client
int n, len;
//So hieu cong dich vu (port number) truyen tu tham so dong lenh
if (argc < 2) {
fprintf(stderr,"ERROR, no port provided\n");
exit(1);
}
portno = atoi(argv[1]); //chuyen thanh so nguyen
//Khoi tao gia tri cho cac vung nho
memset(&serv_addr, '0', sizeof(serv_addr));
memset(&client_addr, '0', sizeof(client_addr));
memset(sendbuff, '0', 256);
//Thiet lap dia chi server
serv_addr.sin_family = AF_INET; //default
serv_addr.sin_addr.s_addr = INADDR_ANY; //ip server
serv_addr.sin_port = htons(portno); //port number
//Tao socket
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR opening socket");
//bind socket
if (bind(sockfd, (struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0)
error("ERROR on binding");
//listening
listen(sockfd,5); //Toi da 5 backlog trong hang doi
len = sizeof(client_addr); //Dung de lay thong tin dia chi client ket noi den
//Server su dung mot vong lap de lien tuc nghe va phuc vu client ket noi den
while(1){
printf("Server is listening at port %d\n", portno);
newsockfd = accept(sockfd, (struct sockaddr *) &client_addr, (socklen_t*)&len);
if (newsockfd < 0)
{
error("ERROR on accept");
continue;
}
char s[255]; //Chua thong tin dia chi client ket noi den
inet_ntop(client_addr.sin_family,(struct sockaddr *)&client_addr,s, sizeof s);
printf("server: got connection from %s\n", s);
memset(recvbuff, 0, 256);
//read data from socket
n = read(newsockfd,recvbuff,255); //block den khi co du lieu tu client gui toi
if (n < 0) error("ERROR reading from socket");
printf("Message from client: %s\n",recvbuff);
//write data via socket
strcpy(sendbuff, "Server has got message\n");
n = write(newsockfd,sendbuff,sizeof(sendbuff));
if (n < 0) error("ERROR writing to socket");
close(newsockfd); //Dong ket noi cua client
sleep(1);
}
close(sockfd);
return 0;
}
Bạn có đam mê ngành thiết kế vi mạch và bạn muốn có mức lương 1000 usd cùng lúc bạn
đang muốn tìm một Trung tâm để học vậy hãy đến với ngành vi mạch tại SEMICON
HotLine: 0972 800 931 Ms Duyên