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()) Đóng kếtnối bằng hàm close()
Chương trình khởi tạo socket trên client: void init_socket()
{
int portno=9000;
struct sockaddr_in serv_addr;
sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0)
printf("ERROR opening socket");
memset(&serv_addr, '0', sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_port = htons(portno); if(inet_pton(AF_INET,"118.71.4.45", &serv_addr.sin_addr)<=0) {
printf("\n inet_pton error occured\n"); }
if( connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
{
printf("\n Error : Connect Failed \n"); }
}
4.3.3. Lập trình đa luồng
Chương trình lập trình cho board được chia làm 2 tiên trình chạy song song với nhau. 2 tiến trình gồm: 1 tiến trình gửi yêu cầu và nhận dữ liệu từ server và 1 tiến trình phát âm thanh nhận được ra đầu ra audio (loa).
Để tạo được 2 tiến trình chạy song song ta dùng giải pháp lập trình đa luồng (thread). Mỗi thread xác định một luồng đơn, thực thi trong phạm vi một chương trình. Khi một chương trình thực thi trên CPU, nó thực hiện các câu lệnh chương trình trong một luồng đơn tới khi luồng hoàn thành.
Viết ứng dụng đơn giản thực hiện tạo luồng, ta dùng hàm pthread_create. pthread_create(&thread_id1, NULL, &nhan_du_lieu, NULL);
pthread_create(&thread_id2, NULL, &phat_am, NULL); Ví dụ: tạo 2 luồng in ra màn hình 2 chữ x và o đan xen nhau.
#include <stdio.h> #include <pthread.h>
void* print_x(void* unused) { while(1) { fputc('x',stdout); }return NULL; }
{
pthread_t thread_id;
pthread_create(&thread_id, NULL, &print_x, NULL); while(1) { fputc('o',stdout); } return 0; }
4.3.4.Thư viện TinyALSA
TinyALSA là một thư viện nhỏ để giao tiếp với ALSA trong nhân Linux, nó cung cấp API pcm và mixer cơ bản.
4.3.4.1. Cài thư viện TinyALSA trên Raspberry
Copy thư viện tinyalsa đã giải nén vào raspberry sau đó và cửa sổ lệnh gõ các lệnh sau (Vào thư trong mục tinyalsa bằng lệnh cd “tên thư mục “ ví dụ cd tinyalsa):
make
sudo make install sudo ldconfig
Sau khi hoàn tất 3 lệnh trên thư viện tinyalsa sẽ cài xong. Để biên dịch chương trình.ta dùng lệnh trên Terminal
gcc -o source source.c -ltinyalsa –lpthread (Trong đó source.c là thư mục chứa code, biên dịch bằng gcc được tệp thực thi source , khai báo 2 thư viện sử dụng là ltinyalsa và lpthread).
4.3.4.2. Hàm xử lí âm thanh trên thư viện TinyALSA
Thư viện TinyALSA có các hàm hỗ trợ xử lý âm thanh sau:
-card: Xác định card cho pcm. Card mặc định bằng 0. -device: Xác định device sử dụng, device mặc định bằng 0
-flags: Chỉđịnh đặc điểm và chức năng về pcm. Đặt flags = PCM_OUT để phát -config: Các thông số phần cứng và phần mềm để mở PCM.Được khai báo dạng const struct pcm_config. Trong đó có cài đặt tốc độđọc, số kênh, định dạng pcm, Độ lớn của chu kỳ hoạt động pcm
*Giá trị trả về dạng PCM struct
* Nếu xảy ra lỗi ở cấp phát bộ nhớ cho PCM, trả về NULL.
* Mặt khác, client phải kiểm tra xem PCM đã mở đúng bằng cách gọi hàm kiểm tra pcm_is_ ready()
pcm_writei(struct pcm *pcm, const void *data, unsigned int frame_count)
Ghi audio samples vào PCM.
* Nếu PCM chưa được khởi động, nó được khởi động trong hàm này. * Chức năng này chỉ hợp lệ cho các PCM được mở bằng cờ PCM_OUT. - pcm: PCM được trả về bởi hàm pcm_open()
- data: Mảng audio samples
- frame_count: Sốlượng frameschứa mảng samples.
* return: Khi hoàn thành, chức năng này trả về sốlượng frames được viết; nếu không trả về một số âm.
pcm_close(struct pcm *pcm)
Hàm này có chức năng đóng PCM struct được tạo bởi hàm pcm_open() - pcm : PCM được trả về bởi pcm_open()
4.3.5. Nhận và xử lý âm thanh
Chương trình lập trình cho board được chia làm 2 tiến trình chạy song song với nhau. 2 tiến trình gồm: 1 tiến trình gửi yêu cầu và nhận dữ liệu từ server và 1 tiến trình phát âm thanh nhận được ra đầu ra audio (loa).
Để tạo được 2 tiến trình chạy song song ta dùng giải pháp lập trình đa luồng (thread). Mỗi thread xác định một luồng đơn, thực thi trong phạm vi một chương trình. Khi một chương trình thực thi trên CPU, hai luồng chạy song song với nhau.