- vừa được xem lúc

Lập trình socket, giao tiếp client và server bằng ngôn ngữ C (với giao thức TCP)

0 0 164

Người đăng: bonbonsayhii

Theo Viblo Asia

Lập trình mạng là gì?

Có bao giờ bạn thắc mắc những chương trình bạn viết ra hoạt động, giao tiếp thế nào trong mạng máy tính chưa? Hay dễ hiểu là làm cách nào để server của bạn có thể nói chuyện được với client?

Lập trình mạng là một trong những nhiệm vụ căn bản để phát triển các ứng dụng. Một chương trình mạng được viết ra để các chương trình trên các máy tính khác nhau có thể truyền tin với nhau một cách hiệu quả và an toàn cho dù chúng được cài đặt trên mạng LAN, WAN hay mạng toàn cầu Internet, đây là điều căn bản đối với sự thành công của nhiều hệ thống.

Hãy cùng mình nghịc thử để viết 1 chương trình socket giao tiếp client và server đơn giản nhất!

Giới thiệu về Socket

SocKet là một giao diện lập trình (API – Application Program Interface) ứng dụng mạng thông qua giao diện này có thể lập trình điều khiển việc truyền thông giữa 2 máy sử dụng các giao thức mức thấp như TCP,UDP… , Có thể tưởng tượng nó như một thiết bị truyền thông 2 chiều tương tự như tệp tin, chúng ta gửi/nhận dữ liệu giữa 2 máy, tương tự như việc đọc ghi trên tệp tin.

Với mô hình khách chủ TCP

Bây giờ chúng ta sẽ bắt tay tìm hiểu cách làm và thực hành

Viết chương trình phía server

Các bước để tạo lên 1 chương trình phía server:

  • Tạo socket với hàm socket (int family, int type, int protocol) các tham số trong đó theo thứ tự là họ giao thức, kiểu socket, kiểu giao thức.
  • Gán địa chỉ cho socket bind (int sockfd, const struct sockaddr *sockaddr, socklen_t addrlen) các tham số lần lượt là mô tả socket vừa tạo, con trỏ chỏ đến địa chỉ socket, độ lớn địa chỉ
  • Chỉ định socket lắng nghe kết nối listen (int sockfd, int backlog) trong đó sockfd là mô tả socket vừa tạo, backlog là số lượng tối đa các kết nối đang chờ
  • Chờ/chấp nhận kết nối accept (int sockfd, struct sockaddr *cliaddr, socklen_t *addrlen) lần lượt có các tham số là mô tả socket vừa tạo, con trỏ tới cấu trúc địa chỉ socket của tiến trình kết nối đến, độ lớn cấu trúc địa chỉ
  • Thiết lập kết nối với máy chủ TCP connect (int sockfd, const struct sockaddr *servaddr, socklen_t addrlen)

Viết chương trình phía client

Các bước để tạo lên 1 chương trình phía client

  • Tạo socket với hàm socket (int family, int type, int protocol) các tham số trong đó theo thứ tự là họ giao thức, kiểu socket, kiểu giao thức.
  • Connect tới địa chỉ server với hàm connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)
  • Đọc dữ liệu từ server và ghi vào biến buffer read( sock , buffer, 1024)

Sau đây mình sẽ đi vào thực hành với 1 requirement đơn giản là:

Mô tả chương trình:

  • server mở công kết nối 8080
  • client nhập địa chỉ ip để kết nối với server qua cổng 8080
  • server hiển thị địa chỉ ip và cổng của client,
  • người dùng nhập chuỗi kí tự bất kì từ bàn phím
  • client đọc chuỗi kí tự và gửi cho server
  • server nhận tin nhắn từ client và trả về tin nhắn nhận được đã viết hoa các kí tự.
  • client hiển thị thông báo từ server
  • lặp đến khi client nhập”bye” thì đóng kết nối.

Code phía server

#include <unistd.h> #include <stdio.h> #include <sys/socket.h> #include <stdlib.h> #include <netinet/in.h> #include <string.h>
#include <ctype.h>
#define PORT 8080 int main(int argc, char const *argv[]) { int server_fd, new_socket, valread; struct sockaddr_in address; int opt = 1; int addrlen = sizeof(address); char mess_from_client[225]; char buffer[1024] = {0}; char *hello = "Hello from server"; int continu = 1; //tao socket // tao file mo ta soket if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) { perror("socket failed"); exit(EXIT_FAILURE); } //gan dia chi cho socket // gan cong port 8080 if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) { perror("setsockopt"); exit(EXIT_FAILURE); } address.sin_family = AF_INET; address.sin_addr.s_addr = INADDR_ANY; address.sin_port = htons( PORT ); //gan cong la 8080 // bind if (bind(server_fd, (struct sockaddr *)&address, sizeof(address))<0) { perror("bind failed"); exit(EXIT_FAILURE); } //listen, chi dinh socket lang nghe ket noi if (listen(server_fd, 3) < 0) { perror("listen"); exit(EXIT_FAILURE); } //accept, chap nhan ket noi if ((new_socket = accept(server_fd, (struct sockaddr *)&address,(socklen_t*)&addrlen))<0) { perror("accept"); exit(EXIT_FAILURE); } while(continu == 1){ char str_cli_ip[INET_ADDRSTRLEN]; struct sockaddr_in* ip_client = (struct sockaddr_in*)&address; inet_ntop(AF_INET, &ip_client->sin_addr, str_cli_ip, INET_ADDRSTRLEN); printf("ipclient: %s\n", str_cli_ip ); char str_cli_port[INET_ADDRSTRLEN]; printf("port: %d\n", ntohs(ip_client->sin_port)); printf("Tin nhan ban nhan dc tu client: \n"); //read, doc du lieu gan vao bien valread tra ve so byte ma no doc duoc valread = read( new_socket, buffer, 1024); //viet hoa ToUp(buffer); //gan bien hello tra ve cho client la buffer da viet hoa hello = &buffer; printf("%s\n",buffer ); send(new_socket, hello, strlen(hello), 0 ); } close(new_socket); return 0; } void ToUp( char *p ) { while( *p ) { *p=toupper( *p ); p++; } } 

Code phía client

#include <stdio.h> #include <sys/socket.h> #include <stdlib.h> #include <netinet/in.h> #include <string.h> #define PORT 8080 int main(int argc, char const *argv[]) { struct sockaddr_in address; int sock = 0, valread; struct sockaddr_in serv_addr; char *hello = "Hello from client"; char buffer[1024] = {0}; char add[225]; int continu = 1; printf("Nhap dia chi server\n"); gets(add); //tao socket if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { printf("\n Socket creation error \n"); return -1; } memset(&serv_addr, '0', sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_port = htons(PORT); // Convert IPv4 and IPv6 addresses from text to binary form if(inet_pton(AF_INET, add, &serv_addr.sin_addr) <= 0) { printf("\nInvalid address/ Address not supported \n"); return -1; } // connect if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) { printf("\nConnection Failed \n"); return -1; } while(continu == 1){ char mess_from_client[225]; printf("Nhap noi dung tin nhan gui den server\n"); gets(mess_from_client); fflush(stdin); hello = &mess_from_client; printf("Tin nhan ban nhan dc tu server: \n"); send(sock , hello , strlen(hello) , 0 ); // printf("Hello message sent\n"); valread = read( sock , buffer, 1024); printf("%s\n",buffer ); if (strcmp(mess_from_client, "bye") == 0) { continu = 0; } fflush(stdin); } close(sock); return 0; } 

Sau khi build và run mình sẽ được thành quả như sau

Đó là demo về 1 chương trình socket sử dụng ngôn ngữ C đơn giản nhất để tìm hiểu về lập trình mạng, cảm ơn bạn đã đọc nhé.

Bình luận

Bài viết tương tự

- vừa được xem lúc

Giới thiệu Typescript - Sự khác nhau giữa Typescript và Javascript

Typescript là gì. TypeScript là một ngôn ngữ giúp cung cấp quy mô lớn hơn so với JavaScript.

0 0 525

- vừa được xem lúc

Cài đặt WSL / WSL2 trên Windows 10 để code như trên Ubuntu

Sau vài ba năm mình chuyển qua code trên Ubuntu thì thật không thể phủ nhận rằng mình đã yêu em nó. Cá nhân mình sử dụng Ubuntu để code web thì thật là tuyệt vời.

0 0 396

- vừa được xem lúc

Đặt tên commit message sao cho "tình nghĩa anh em chắc chắn bền lâu"????

. Lời mở đầu. .

1 1 737

- vừa được xem lúc

Tìm hiểu về Resource Controller trong Laravel

Giới thiệu. Trong laravel, việc sử dụng các route post, get, group để gọi đến 1 action của Controller đã là quá quen đối với các bạn sử dụng framework này.

0 0 358

- vừa được xem lúc

Phân quyền đơn giản với package Laravel permission

Như các bạn đã biết, phân quyền trong một ứng dụng là một phần không thể thiếu trong việc phát triển phần mềm, dù đó là ứng dụng web hay là mobile. Vậy nên, hôm nay mình sẽ giới thiệu một package có thể giúp các bạn phân quyền nhanh và đơn giản trong một website được viết bằng PHP với framework là L

0 0 449

- vừa được xem lúc

Bạn đã biết các tips này khi làm việc với chuỗi trong JavaScript chưa ?

Hi xin chào các bạn, tiếp tục chuỗi chủ đề về cái thằng JavaScript này, hôm nay mình sẽ giới thiệu cho các bạn một số thủ thuật hay ho khi làm việc với chuỗi trong JavaScript có thể bạn đã hoặc chưa từng dùng. Cụ thể như nào thì hãy cùng mình tìm hiểu trong bài viết này nhé (go).

0 0 433