Jika Anda menyetel soket beroperasi dalam mode non-pemblokiran, setiap panggilan untuk membaca hanya akan membaca data yang saat ini tersedia (jika ada). Jadi ini secara efektif sama dengan waktu tunggu langsung.
Anda dapat menyetel mode non-pemblokiran pada soket dengan fungsi seperti ini:
int setnonblock(int sock) {
int flags;
flags = fcntl(sock, F_GETFL, 0);
if (-1 == flags)
return -1;
return fcntl(sock, F_SETFL, flags | O_NONBLOCK);
}
(Untuk informasi selengkapnya tentang membaca dari soket non-pemblokiran, lihat read
halaman manual)
Anda tidak mengatakan apa OS itu tetapi jika Anda menjalankan Linux, Anda dapat menggunakan panggilan pilih. Ini kembali jika ada sesuatu untuk dibaca pada deskriptor file atau Anda dapat mengaturnya sehingga akan habis waktu jika tidak ada yang dibaca. Kode pengembalian menunjukkan yang mana.
Sebagai alternatif dari select()
, untuk kasus khusus port serial (terminal) Anda dapat menggunakan tcsetattr()
untuk menempatkan deskriptor file ke mode non-kanonik, dengan waktu tunggu baca.
Untuk melakukannya, batalkan setelan ICANON
bendera, dan atur VTIME
karakter kontrol:
struct termios termios;
tcgetattr(filedesc, &termios);
termios.c_lflag &= ~ICANON; /* Set non-canonical mode */
termios.c_cc[VTIME] = 100; /* Set timeout of 10.0 seconds */
tcsetattr(filedesc, TCSANOW, &termios);
Perhatikan VTIME
diukur dalam sepersepuluh detik, dan jenis yang digunakan biasanya adalah unsigned char
, artinya batas waktu maksimum adalah 25,5 detik.
pilih () mengambil 5 parameter, pertama deskriptor file tertinggi + 1, kemudian fd_set untuk membaca, satu untuk menulis dan satu untuk pengecualian. Parameter terakhir adalah struct timeval, digunakan untuk timeout. Itu mengembalikan -1 pada kesalahan, 0 pada waktu tunggu atau jumlah deskriptor file di set yang disetel.
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/select.h>
int main(void)
{
fd_set set;
struct timeval timeout;
int rv;
char buff[100];
int len = 100;
int filedesc = open( "dev/ttyS0", O_RDWR );
FD_ZERO(&set); /* clear the set */
FD_SET(filedesc, &set); /* add our file descriptor to the set */
timeout.tv_sec = 0;
timeout.tv_usec = 10000;
rv = select(filedesc + 1, &set, NULL, NULL, &timeout);
if(rv == -1)
perror("select"); /* an error accured */
else if(rv == 0)
printf("timeout"); /* a timeout occured */
else
read( filedesc, buff, len ); /* there was data to read */
close(filedesc);
}