Giriş
Linux'ta şu satırlar dahil edilir.
Winsock API'si SOCKET yapısı ile çalışıyor gibi görünüyor. Ancak altta SOCKET aslında unsigned int. Linux'ta ise socket API'si int ile çalışıyor. Ortak bir yapı için int olarak tutulabilir.
Socket Açmak
Örnek
Winsock ve Linux'ta şöyle yaparız.
Şu kullanım da doğru
Şöyle yaparız.
Sunucu socketlerde kullanılır.
Örnek
Şöyle yaparız.
Eğer tüm ağ arayüzlerini değil sadece belli bir ağ arayüzünü dinlemek istersek şöyle yaparız.
Adres şöyle de doldurulabilir. bzero veya memzero ile tüm alanları sıfırlarız.
Şöyle yaparız.
Winsock'ta şöyle yaparız.
Metodun imzası şöyle
Şöyle yaparız.
Şöyle yaparız.
Windows'ta şöyle yaparız.
Linux'ta şu satırlar dahil edilir.
#include<sys/socket.h>
#include<sys/types.h>
#include<netinet/in.h>
Windows'ta şu satır dahil edilir.#include <Winsock2.h>
Windows'ta socket kütüphanesini ilklendirmek için şöyle yaparız.WORD wVersionRequested= MAKEWORD(2, 2);WSADATA wsaData;
int err = WSAStartup(wVersionRequested, &wsaData);
if (err != 0) {
printf("WSAStartup failed with error: %d\n", err);
}
Socket HandleWinsock API'si SOCKET yapısı ile çalışıyor gibi görünüyor. Ancak altta SOCKET aslında unsigned int. Linux'ta ise socket API'si int ile çalışıyor. Ortak bir yapı için int olarak tutulabilir.
Socket Açmak
Örnek
Winsock ve Linux'ta şöyle yaparız.
int
fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
ÖrnekŞu kullanım da doğru
int fd = socket(AF_INET,SOCK_DGRAM,0);
Açıklaması şöyleEğer hata varsa <0 döner. Şöyle yaparız.The only valid values for protocol are 0 and IPPROTO_TCP for TCP sockets, and 0 and IPPROTO_UDP for UDP sockets. For SOCK_RAW you may specify a valid IANA IP protocol defined in RFC 1700 assigned numbers.
if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
perror("cannot create socket\n");
}
ÖrnekŞöyle yaparız.
// Create the socket
SOCKET mSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (!mSocket) {
printf("Socket failed with error code : %d", WSAGetLastError());
}
bindSunucu socketlerde kullanılır.
Örnek
Şöyle yaparız.
struct sockaddr_in local;
local.sin_family = AF_INET;
local.sin_port = htons(54164);
local.sin_addr.s_addr = htonl (INADDR_ANY);
bind(fd, (struct sockaddr *) &local
, sizeof(local));
Eğer hata varsa < 0 döner. Şöyle yaparız.if (bind(fd, (struct sockaddr *)local, sizeof(local)) < 0) {
perror("bind failed");
}
ÖrnekEğer tüm ağ arayüzlerini değil sadece belli bir ağ arayüzünü dinlemek istersek şöyle yaparız.
local.sin_addr.s_addr = inet_addr("127.0.0.1");
ÖrnekAdres şöyle de doldurulabilir. bzero veya memzero ile tüm alanları sıfırlarız.
struct sockaddr_in servaddr;
bzero(&servaddr,sizeof(servaddr));
servaddr.sin_family =AF_INET;
servaddr.sin_port = htons (
54164);
Sebebi ise INADDR_AYN değerinin 0 olması.# define INADDR_ANY ((unsigned long int) 0x00000000)
ÖrnekŞöyle yaparız.
sockaddr_in socketAddr = { 0 };
socketAddr.sin_family = PF_INET;
socketAddr.sin_port = htons(1010);
socketAddr.sin_addr.s_addr = INADDR_ANY;
//Bind
if (bind(socket, (struct sockaddr *)&socketAddr, sizeof(socketAddr)) == SOCKET_ERROR) {
printf("Bind failed with error code : %d", WSAGetLastError());
}
close metoduWinsock'ta şöyle yaparız.
::closesocket (
fd);
Linux'ta şöyle yaparız.::close (
fd);
shutdown metoduMetodun imzası şöyle
int shutdown (int s, int how); // s is socket descriptor
Windows'ta kullanılan parametreler Linux'tan farklı. Windows'ta şöyle yaparız.::shutdown (fd, SD_BOTH); //SD_RECEIVE , SD_SEND
Linux'ta şöyle yaparız.::shutdown (fd, SHUT_RDWR); //SHUT_RD, SHUTWR
getAvailableBytesŞöyle yaparız.
int bytesAvailable = 0;
ioctl (fd,FIONREAD,&bytesAvailable);
return bytesAvailable;
getLocalPortŞöyle yaparız.
struct sockaddr_in addr;
int len = sizeof(struct addr);
getsockname(fd, (struct sockaddr *) &addr, &len);
return ntohs (addr.sin_port);
getLastError metoduWindows'ta şöyle yaparız.
return WSAGetLastError();
Linux'ta şöyle yaparız.return errno;
recvfrom metodu
İlk parametre socket, ikinci parametre verinin okunacağı alan, üçüncü parametre alanın büyüklüğü, dördüncü parametre flags ama hep 0 kullanılır, beşinci parametre veriyi gönderen adres, altıncı parametre adresin büyüklüğüdür.Örnek
Şöyle yaparız.
Şöyle yaparız.
#define BUFLEN 512
struct sockaddr_in claddr; // address of the client
char buf[BUFLEN];
socklen_t clientlen = sizeof(claddr);
long recvlen=recvfrom(fd, buf, BUFLEN, 0, (struct sockaddr *)&claddr, &clientlen);
Eğer hata yoksa > 0 okunur. Bu durumda karakter okuyorsak şöyle yaparız.
Şöyle yaparız.
İlk parametre socket, ikinci parametre gönderilecek veri, üçüncü parametre verinin büyüklüğü, dördünce parametre flags ama hep 0 kullanılır, beşinci parametre gönderilecek adres, altıncı parametre ise adresin büyüklüğüdür.if (recvlen > 0) {
buf[recvlen] = 0;
}
ÖrnekŞöyle yaparız.
// Receive and time
char buffer[50];
sockaddr_in senderAddr;
int senderAddrSize = sizeof(senderAddr);
int transferred = recvfrom(mSocket, (char*)buffer, 50, 0,
(sockaddr*)&senderAddr, &senderAddrSize);
sendto metodu
Örnek
Şöyle yaparız.
setsockopt metodu
SO_RCVBUF
Receive Buffer Size'ı öğrenmek için şöyle yaparız.
SO_BROADCAST
Winsock ve Linux'ta şöyle yaparız.
char buf[512];struct sockaddr_in servaddr; // server's address
socklen_t slen = sizeof(servaddr);
sendto(fd, buf,
sizeof(buf), 0, (struct sockaddr *)&servaddr, slen) < 0)
Adres şöyle doldurulur.struct sockaddr_in servaddr;
bzero(&servaddr,sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(6349);inet_pton (AF_INET,"...",&servaddr.sin_addr);
Eğer socketin gönderme belleğinde yer yoksa hata kodu olarak Linux'ta EMSGSIZE alırız.setsockopt metodu
SO_RCVBUF
Receive Buffer Size'ı öğrenmek için şöyle yaparız.
int bufSize = 65535;
setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &bufSize, sizeof(int)
return
bufSize;
SO_RCVTIMEO
Bu değer Windows'ta en az 500 ms olmalı. Açıklaması şöyle.
Winsock ve Linux'ta şöyle yaparız. Aynı adrese birden fazla socketin bağlanmasına izin verir. Özellikle sunucu socket için bind() yapmadan önce kullanılır.Bu değer Windows'ta en az 500 ms olmalı. Açıklaması şöyle.
Şöyle yaparız.There is an undocumented minimum limit of about 500mS on SO_RCVTIMEO.
// Set timeout
DWORD lBuffer[2] = { 0, 0 };
int lSize;
lBuffer[0] = static_cast<DWORD>(1000.0 * timeout);
lSize = sizeof(DWORD);
if (setsockopt(mSocket, SOL_SOCKET, SO_RCVTIMEO, (char*)lBuffer, lSize) != 0) {
printf("Set socket option failed with error code : %d", WSAGetLastError());
}
// Check that we get what we set.
DWORD lBufferout[2] = { 0, 0 };
if (getsockopt(mSocket, SOL_SOCKET, SO_RCVTIMEO, (char*)lBufferout, &lSize) != 0) {
printf("Get socket option failed with error code : %d", WSAGetLastError());
}
SO_REUSEADDRint enable = 1;
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(enable)) < 0)
SO_BROADCAST
Winsock ve Linux'ta şöyle yaparız.
int broadcast = 1;
// this call is what allows broadcast packets to be sent:
setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof (broadcast));
Hiç yorum yok:
Yorum Gönder