Soket Unix - Fungsi Inti
Bab ini menjelaskan fungsi soket inti yang diperlukan untuk menulis klien dan server TCP lengkap.
Diagram berikut menunjukkan interaksi Klien dan Server lengkap -
Fungsi soket
Untuk melakukan I / O jaringan, hal pertama yang harus dilakukan oleh proses adalah memanggil fungsi soket, menentukan jenis protokol komunikasi yang diinginkan dan keluarga protokol, dll.
#include <sys/types.h>
#include <sys/socket.h>
int socket (int family, int type, int protocol);
Panggilan ini mengembalikan deskriptor soket yang dapat Anda gunakan di panggilan sistem nanti atau -1 pada kesalahan.
Parameter
family - Ini menentukan keluarga protokol dan merupakan salah satu konstanta yang ditunjukkan di bawah ini -
Keluarga | Deskripsi |
---|---|
AF_INET | Protokol IPv4 |
AF_INET6 | Protokol IPv6 |
AF_LOCAL | Protokol domain Unix |
AF_ROUTE | Soket Perutean |
AF_KEY | Soket Ket |
Bab ini tidak membahas protokol lain kecuali IPv4.
type- Ini menentukan jenis soket yang Anda inginkan. Ini dapat mengambil salah satu dari nilai berikut -
Tipe | Deskripsi |
---|---|
SOCK_STREAM | Soket aliran |
SOCK_DGRAM | Soket datagram |
SOCK_SEQPACKET | Soket paket berurutan |
SOCK_RAW | Soket mentah |
protocol - Argumen harus disetel ke jenis protokol khusus yang diberikan di bawah ini, atau 0 untuk memilih default sistem untuk kombinasi keluarga dan jenis yang diberikan -
Protokol | Deskripsi |
---|---|
IPPROTO_TCP | Protokol transport TCP |
IPPROTO_UDP | Protokol transportasi UDP |
IPPROTO_SCTP | Protokol transport SCTP |
The connect Fungsi
Fungsi menghubungkan digunakan oleh klien TCP untuk membuat sambungan dengan server TCP.
#include <sys/types.h>
#include <sys/socket.h>
int connect(int sockfd, struct sockaddr *serv_addr, int addrlen);
Panggilan ini mengembalikan 0 jika berhasil terhubung ke server, jika tidak maka akan mengembalikan -1 pada kesalahan.
Parameter
sockfd - Ini adalah deskriptor soket yang dikembalikan oleh fungsi soket.
serv_addr - Ini adalah penunjuk ke struct sockaddr yang berisi alamat IP tujuan dan port.
addrlen - Setel ke sizeof (struct sockaddr).
The mengikat Fungsi
Fungsi bind memberikan alamat protokol lokal ke soket. Dengan protokol Internet, alamat protokol adalah kombinasi dari alamat IPv4 32-bit atau alamat IPv6 128-bit, bersama dengan nomor port TCP atau UDP 16-bit. Fungsi ini hanya dipanggil oleh server TCP.
#include <sys/types.h>
#include <sys/socket.h>
int bind(int sockfd, struct sockaddr *my_addr,int addrlen);
Panggilan ini mengembalikan 0 jika berhasil mengikat ke alamat, jika tidak maka akan mengembalikan -1 pada kesalahan.
Parameter
sockfd - Ini adalah deskriptor soket yang dikembalikan oleh fungsi soket.
my_addr - Ini adalah penunjuk ke struct sockaddr yang berisi alamat IP lokal dan port.
addrlen - Setel ke sizeof (struct sockaddr).
Anda dapat memasukkan alamat IP dan port Anda secara otomatis
Nilai 0 untuk nomor port berarti sistem akan memilih port acak, dan nilai INADDR_ANY untuk alamat IP berarti alamat IP server akan ditetapkan secara otomatis.
server.sin_port = 0;
server.sin_addr.s_addr = INADDR_ANY;
NOTE- Semua port di bawah 1024 sudah dipesan. Anda dapat mengatur port di atas 1024 dan di bawah 65535 kecuali port tersebut digunakan oleh program lain.
The mendengarkan Fungsi
Fungsi mendengarkan hanya dipanggil oleh server TCP dan melakukan dua tindakan -
Fungsi mendengarkan mengubah soket yang tidak terhubung menjadi soket pasif, yang menunjukkan bahwa kernel harus menerima permintaan koneksi masuk yang diarahkan ke soket ini.
Argumen kedua untuk fungsi ini menentukan jumlah maksimum koneksi yang harus antri kernel untuk soket ini.
#include <sys/types.h>
#include <sys/socket.h>
int listen(int sockfd,int backlog);
Panggilan ini mengembalikan 0 jika berhasil, jika tidak maka akan mengembalikan -1 pada kesalahan.
Parameter
sockfd - Ini adalah deskriptor soket yang dikembalikan oleh fungsi soket.
backlog - Ini adalah jumlah koneksi yang diizinkan.
The menerima Fungsi
Fungsi terima dipanggil oleh server TCP untuk mengembalikan koneksi selesai berikutnya dari depan antrian koneksi yang sudah selesai. Tanda tangan panggilan tersebut adalah sebagai berikut -
#include <sys/types.h>
#include <sys/socket.h>
int accept (int sockfd, struct sockaddr *cliaddr, socklen_t *addrlen);
Panggilan ini mengembalikan deskriptor non-negatif tentang sukses, jika tidak maka akan mengembalikan -1 pada kesalahan. Deskriptor yang dikembalikan diasumsikan sebagai deskriptor soket klien dan semua operasi baca-tulis akan dilakukan pada deskriptor ini untuk berkomunikasi dengan klien.
Parameter
sockfd - Ini adalah deskriptor soket yang dikembalikan oleh fungsi soket.
cliaddr - Ini adalah penunjuk ke struct sockaddr yang berisi alamat IP dan port klien.
addrlen - Setel ke sizeof (struct sockaddr).
The kirim Fungsi
Fungsi kirim digunakan untuk mengirim data melalui soket aliran atau soket datagram TERHUBUNG. Jika Anda ingin mengirim data melalui soket datagram TIDAK TERSAMBUNG, Anda harus menggunakan fungsi sendto ().
Anda dapat menggunakan panggilan sistem write () untuk mengirim data. Tanda tangannya adalah sebagai berikut -
int send(int sockfd, const void *msg, int len, int flags);
Panggilan ini mengembalikan jumlah byte yang dikirim, jika tidak maka akan mengembalikan -1 pada kesalahan.
Parameter
sockfd - Ini adalah deskriptor soket yang dikembalikan oleh fungsi soket.
msg - Ini adalah penunjuk ke data yang ingin Anda kirim.
len - Ini adalah panjang data yang ingin Anda kirim (dalam byte).
flags - Sudah disetel ke 0.
The recv Fungsi
Fungsi recv digunakan untuk menerima data melalui soket aliran atau soket datagram TERHUBUNG. Jika Anda ingin menerima data melalui soket datagram TIDAK TERSAMBUNG Anda harus menggunakan recvfrom ().
Anda dapat menggunakan panggilan sistem read () untuk membaca data. Panggilan ini dijelaskan di bab fungsi pembantu.
int recv(int sockfd, void *buf, int len, unsigned int flags);
Panggilan ini mengembalikan jumlah byte yang dibaca ke dalam buffer, jika tidak maka akan mengembalikan -1 pada kesalahan.
Parameter
sockfd - Ini adalah deskriptor soket yang dikembalikan oleh fungsi soket.
buf - Ini adalah buffer untuk membaca informasi.
len - Ini adalah panjang maksimum buffer.
flags - Sudah disetel ke 0.
The sendto Fungsi
Fungsi sendto digunakan untuk mengirim data melalui soket datagram TIDAK TERSAMBUNG. Tanda tangannya adalah sebagai berikut -
int sendto(int sockfd, const void *msg, int len, unsigned int flags, const struct sockaddr *to, int tolen);
Panggilan ini mengembalikan jumlah byte yang dikirim, jika tidak maka akan mengembalikan -1 pada kesalahan.
Parameter
sockfd - Ini adalah deskriptor soket yang dikembalikan oleh fungsi soket.
msg - Ini adalah penunjuk ke data yang ingin Anda kirim.
len - Ini adalah panjang data yang ingin Anda kirim (dalam byte).
flags - Sudah disetel ke 0.
to - Ini adalah penunjuk ke struct sockaddr untuk host tempat data harus dikirim.
tolen - Sudah disetel ke sizeof (struct sockaddr).
The recvfrom Fungsi
Fungsi recvfrom digunakan untuk menerima data dari soket datagram UNCONNECTED.
int recvfrom(int sockfd, void *buf, int len, unsigned int flags struct sockaddr *from, int *fromlen);
Panggilan ini mengembalikan jumlah byte yang dibaca ke buffer, jika tidak maka akan mengembalikan -1 pada kesalahan.
Parameter
sockfd - Ini adalah deskriptor soket yang dikembalikan oleh fungsi soket.
buf - Ini adalah buffer untuk membaca informasi.
len - Ini adalah panjang maksimum buffer.
flags - Sudah disetel ke 0.
from - Ini adalah penunjuk ke struct sockaddr untuk host tempat data harus dibaca.
fromlen - Sudah disetel ke sizeof (struct sockaddr).
The dekat Fungsi
Fungsi close digunakan untuk menutup komunikasi antara klien dan server. Sintaksnya adalah sebagai berikut -
int close( int sockfd );
Panggilan ini mengembalikan 0 jika berhasil, jika tidak maka akan mengembalikan -1 pada kesalahan.
Parameter
sockfd - Ini adalah deskriptor soket yang dikembalikan oleh fungsi soket.
The Shutdown Fungsi
Fungsi shutdown digunakan untuk menutup komunikasi antara klien dan server dengan baik. Fungsi ini memberikan lebih banyak kontrol dibandingkan dengan fungsi tutup . Diberikan di bawah ini adalah sintaks shutdown -
int shutdown(int sockfd, int how);
Panggilan ini mengembalikan 0 jika berhasil, jika tidak maka akan mengembalikan -1 pada kesalahan.
Parameter
sockfd - Ini adalah deskriptor soket yang dikembalikan oleh fungsi soket.
how - Masukkan salah satu angkanya -
0 - menunjukkan bahwa menerima tidak diperbolehkan,
1 - menunjukkan bahwa pengiriman tidak diperbolehkan, dan
2- menunjukkan bahwa pengiriman dan penerimaan tidak diperbolehkan. Ketika how diatur ke 2, itu sama dengan close ().
The pilih Fungsi
Fungsi pemilihan menunjukkan deskriptor file tertentu yang siap untuk dibaca, siap untuk ditulis, atau memiliki kondisi kesalahan yang tertunda.
Ketika sebuah aplikasi memanggil recv atau recvfrom , itu diblokir sampai data tiba untuk soket itu. Aplikasi dapat melakukan pemrosesan berguna lainnya saat aliran data yang masuk kosong. Situasi lain adalah ketika aplikasi menerima data dari banyak soket.
Memanggil recv atau recvfrom pada soket yang tidak memiliki data dalam antrian inputnya mencegah penerimaan data secara langsung dari soket lain. Panggilan fungsi pemilihan memecahkan masalah ini dengan mengizinkan program untuk mengumpulkan semua pegangan soket untuk melihat apakah mereka tersedia untuk operasi membaca dan menulis non-pemblokiran.
Diberikan di bawah ini adalah sintaks pilih -
int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *errorfds, struct timeval *timeout);
Panggilan ini mengembalikan 0 jika berhasil, jika tidak maka akan mengembalikan -1 pada kesalahan.
Parameter
nfds- Ini menentukan kisaran deskriptor file yang akan diuji. Fungsi select () menguji deskriptor file dalam kisaran 0 hingga nfds-1
readfds- Ini menunjuk ke sebuah objek berjenis fd_set yang pada input, menentukan deskriptor file yang akan diperiksa untuk siap dibaca, dan pada output, menunjukkan deskriptor file mana yang siap untuk dibaca. Bisa NULL untuk menunjukkan set kosong.
writefds- Ini menunjuk ke objek berjenis fd_set yang pada input, menentukan deskriptor file yang akan diperiksa untuk siap menulis, dan pada output, menunjukkan deskriptor file mana yang siap untuk menulis. Bisa NULL untuk menunjukkan set kosong.
exceptfds- Ini menunjuk ke sebuah objek berjenis fd_set yang pada input, menentukan deskriptor file yang akan diperiksa untuk kondisi kesalahan yang tertunda, dan pada output menunjukkan, deskriptor file mana yang memiliki kondisi kesalahan tertunda. Bisa NULL untuk menunjukkan set kosong.
timeout- Ini menunjuk ke struct timeval yang menentukan berapa lama panggilan pilih harus mengumpulkan deskriptor untuk operasi I / O yang tersedia. Jika nilai batas waktu 0, maka pilih akan segera kembali. Jika argumen batas waktu adalah NULL, pilih akan memblokir hingga setidaknya satu pegangan file / soket siap untuk operasi I / O yang tersedia. Jika tidak, pilih akan kembali setelah jumlah waktu dalam batas waktu telah berlalu ATAU ketika setidaknya satu deskriptor file / soket siap untuk operasi I / O.
Nilai kembali dari pilih adalah jumlah pegangan yang ditentukan dalam kumpulan deskriptor file yang siap untuk I / O. Jika batas waktu yang ditentukan oleh bidang batas waktu tercapai, pilih kembali 0. Makro berikut ada untuk memanipulasi kumpulan deskriptor file -
FD_CLR(fd, &fdset)- Menghapus bit untuk deskriptor file fd di set deskriptor file fdset.
FD_ISSET(fd, &fdset)- Mengembalikan nilai bukan nol jika bit untuk deskriptor file fd disetel dalam set deskriptor file yang ditunjukkan oleh fdset , dan 0 sebaliknya.
FD_SET(fd, &fdset) - Menetapkan bit untuk deskriptor file fd dalam set deskriptor file fdset.
FD_ZERO(&fdset) - Menginisialisasi set deskriptor file fdset agar memiliki bit nol untuk semua deskriptor file.
Perilaku makro ini tidak ditentukan jika argumen fd kurang dari 0 atau lebih besar dari atau sama dengan FD_SETSIZE.
Contoh
fd_set fds;
struct timeval tv;
/* do socket initialization etc.
tv.tv_sec = 1;
tv.tv_usec = 500000;
/* tv now represents 1.5 seconds */
FD_ZERO(&fds);
/* adds sock to the file descriptor set */
FD_SET(sock, &fds);
/* wait 1.5 seconds for any data to be read from any single socket */
select(sock+1, &fds, NULL, NULL, &tv);
if (FD_ISSET(sock, &fds)) {
recvfrom(s, buffer, buffer_len, 0, &sa, &sa_len);
/* do something */
}
else {
/* do something else */
}