UDP Broadcast sunucu - istemci

Sunucu:

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>

#define MY_PORT 3333

int main(int argc, char *argv[])
{

    int sockfd, new_fd;
    struct sockaddr_in my_addr;    // hedef adres
    struct sockaddr_in their_addr; // baglanti yapan adres

    int sin_size, rt;

    // gelen verinin tutuldugu buffer
    char buf[32];

    // islem yapmak icin gerekli dosya gosterici
    sockfd = socket(AF_INET, SOCK_DGRAM, 0);

    sin_size = sizeof(struct sockaddr_in);

    // adres ile ilgili ayarlar
    my_addr.sin_family      = AF_INET;
    my_addr.sin_port        = htons(MY_PORT); // kullanilacak port
    my_addr.sin_addr.s_addr = INADDR_ANY;     // mevcut ip adresi
    memset(&(my_addr.sin_zero), 0, 8); // geri kalani 0la

    // socket ile dosyayi iliskilendir
    bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr));

    while ( 1 ) {
        rt = recvfrom (sockfd, buf, 12, 0, (struct sockaddr *)&their_addr, &sin_size);
        if (rt > 0) {
            printf ("recv: %s\n", buf);
        } else if (rt < 0) {
            printf("Baglanti koptu\n");
            break;
        }
    }

    close(sockfd);
    return 0;
}

İstemci:

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>

#define DEST_IP   "255.255.255.255"
#define DEST_PORT 3333

int main(int argc, char *argv[])
{

    int sockfd, new_fd;
    struct sockaddr_in dest_addr; // hedef adres

    int sin_size, rt;
    sin_size = sizeof(struct sockaddr_in);

    // islem yapmak icin gerekli dosya gosterici
    sockfd = socket(AF_INET, SOCK_DGRAM, 0);

    // adres ile ilgili ayarlar
    dest_addr.sin_family      = AF_INET;
    dest_addr.sin_port        = htons(DEST_PORT);
    dest_addr.sin_addr.s_addr = inet_addr(DEST_IP);
    memset(&(dest_addr.sin_zero), 0, 8); // geri kalani 0 la

    // Broadcast icin gerekli yetkiyi al
    int flag = 1;
    if (setsockopt (sockfd, SOL_SOCKET, SO_BROADCAST, &flag, sizeof(flag)) < 0)
        perror("setsockopt");

    // mesaji gonder
    rt = sendto (sockfd, "slm asl plz", 12, 0, (const struct sockaddr *)&dest_addr, sin_size);
    if ( rt < 0 )
        perror("Hata: ");

    // socketi kapat
    close(sockfd);

    return 0;
}

Linux, Paralel Port ile 2x16 LCD Ekran Kullanımı

Çalıştığım projede linuxta paralel port ile lcd ekran kullanmam gerekti. Neredeyse internetin altını üstüne getirdim ama işime yarar çok birşey bulamadım. Sonunda DOS için yazılmış bir kod buldum. Bu kodu biraz inceleyip, gerekli püf noktaları bulunca kodu linux’a uydurmak çok zor olmadı. Hatta neredeyse sadece kullanılan fonksiyonun adını ve parametre yerlerini değiştirdim :)

Aslında olay çok basitmiş, lcd ekrandan çıkan 14 bacaktan, 8tanesini data ve komut göndermek için kullanıyoruz. 1 bacak enable, 1 set - reset seçimi için, 1 bacakta read/write seçimi için kullanılıyor. Geri kalan 3 bacak güç bağlantısı ve kontrast için kullanılıyor. Burdaki şemaya göre bağlantıları yapabilirsiniz. Ayrıca örnek aldığım kodda aynı sayfada bulunmakta.

Yorum satırları pek çok şeyi açıklıyor. Ama birkaç noktaya değinmekte fayda var. Data bacaklarına gerekli inputları verdikten sonra, enable bacağını 1’den 0’a düşürerek lcd’nin data bacaklarında sinyali alıp işleme sokmasını sağlıyoruz. init array’i içinde lcd’nin temizlenmesi ve çalışmaya uygun hale gelmesi için gerekli komutlar tutuluyor. 0x378 paralel portun adresi.

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <asm/io.h>

#define PORTADDRESS 0x378  /* Enter Your Port Address Here */

#define DATA PORTADDRESS+0
#define STATUS PORTADDRESS+1
#define CONTROL PORTADDRESS+2

int main()
{
    if (ioperm(DATA , 3, 1)) {perror("ioperm"); exit(1);}
    char string[] = {"Testing 1,2,3                           "
                     "It' Works !                             "};

    char init[10];
    int count;
    int len;
    init[0] = 0x0F; /* Init Display */
    init[1] = 0x01; /* Clear Display */
    init[2] = 0x38; /* Dual Line / 8 Bits */

    outb(inb(CONTROL) & 0xDF, CONTROL); /* Reset Control Port - Make sure Forward Direction */
    outb(inb(CONTROL) | 0x08, CONTROL); /* Set Select Printer (Register Select) */

    for (count = 0; count < = 2; count++)
    {
        outb(init[count], DATA);
        outb(inb(CONTROL) | 0x01, CONTROL); /* Set Strobe (Enable)*/
        usleep(20);                                 /* Larger Delay for INIT */
        outb(inb(CONTROL) & 0xFE, CONTROL); /* Reset Strobe (Enable)*/
        usleep(20);                                 /* Larger Delay for INIT */
    }

    outb(inb(CONTROL) & 0xF7, CONTROL);  /* Reset Select Printer (Register Select) */

    len = strlen(string);

    for (count = 0; count < len; count++)
    {
        outb(string[count], DATA);
        outb(inb(CONTROL) | 0x01, CONTROL); /* Set Strobe */
        usleep(2);
        outb(inb(CONTROL) & 0xFE, CONTROL); /* Reset Strobe */
        usleep(2);
    }

    return 0;
}

Linke birşey olması durumunda bu adresten gerekli şemayı indirebilirsiniz.


C ile Nesne Yaratmak

Evet kışkırtıcı bir başlık attım :) Aslında yapacağımız olay bir structı nesne gibi kullanmak. Buna benzer bir kodu yıllar önce görmüştüm. O günden bu güne sürekli böyle bir şeyi nasıl yaparım diye araştırdım. Anca bugün çözebildim olayı ;) Kodu aşağıda yorum satırıyla beraber veriyorum. Yorumlarda gerekli açıklamaları yaptım.

Bu yazıyla C-3PO nun ne lakası var diyebilirsiniz. C ile resim ararken karşıma bu çıktı, bende boş durmasın dedim :)

/*
 * Sınıfımızı yaratıyoruz
 */
struct _myobject {
  // alt alanlar
  int a, b;
  /*
   * Metod
   * Burada fonksiyon pointerı tanımlıyoruz
   */
  int (*add)(struct _myobject*);
};

// struct ön ekinden kurtuluyoruz
typedef struct _myobject MyObject;

/*
 * Asıl işi yapacak fonksiyonu tanımlıyoruz
 * MyObject structını parametre olarak alıyor
 */
int realAdd(MyObject* a) {
  return a->a + a->b;
}

int main ( void ) {
  /*
   * Nesnemizi oluşturuyoruz.
   * add pointerına fonksiyonu atıyoruz
   */
  MyObject mo = {1, 2, realAdd};
  printf("A + B = %d\n", mo.add(&mo));
  return 0;
}

Kodun başına stdio.h headerını eklemekte fayda var. WP sıkıntı çıkarttığı için silmek zorunda kaldım. Kodun düzgün halini burada bulabilirsiniz.


Gtk <= 2.18.9 Pencere Gizleme Sorunu

Gtk Gece gece uyku tutmadı var olan bir programı kurcalamaya başladım. Amacım programın sitem çekmecesinden çalışabilir hale getirmekti.

Her şeyi yaptım fakat bir türlü pencereyi gizleyemiyordum :) Doküman gtk_window_get_mnemonics_visible () fonksiyonunu kullanmamı söylüyordu, fakat kullandığım gtk sürümünde bu fonksiyon tanımlı değildi(2.18.7). Eski sürüm için olan dokümanı incelediğimde bu işi yapan bir fonksiyon yoktu. Sistemde kurulu gtk ve python ile bu işi yapabiliyordum. Normal olarak c ile de yapabilmem lazımdı:) Biraz inceledikten sonra, önce pencereyi gizleyen, ardından boyutunu eski haline getirip sonra tekrar gösteren bir fonksiyon olduğunu fark ettim. Benim istediğim işi yapıyor fakat yanında birde fazlalığı vardı.(gtk_window_reshow_with_initial_size) İnternette biraz daha araştırıp umudumu kaybedince mecburen kaynak koda baktım.

grep -rHn gtk_window_reshow_with_initial_size *

bu komut bana gtk_window_reshow_with_initial_size fonksiyonun nerelerde olduğunu gösterdi. Bu fonksiyonunun içine bakınca istediğim kodu hemen buldum :)

gtk_window_reshow_with_initial_size (GtkWindow *window)
{
  GtkWidget *widget;

  g_return_if_fail (GTK_IS_WINDOW (window));

  widget = GTK_WIDGET (window);

  gtk_widget_hide (widget);
  gtk_widget_unrealize (widget);
  gtk_widget_show (widget);
}

Önce pencereyi widgeta çevirebilme imkanım varmış, böyle basit bir şeyi nasıl bulamadım bilemiyorum.


C ile Komut Satırı Argumanları ve Parametreleri

Terminal Komut satırı programları -h yada –help gibi parametreler alırlar. Bu alınan parametrelerin kolay kullanılması için getopt adında bir kütüphane yaratılmış. Bu kütüphane kullanlanılarak çok rahat böyle programlar yazılabilir. Bende bunun için küçük bir örnek yazdım.

#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>

int print_usage ( void );

int main (int argc, char* argv[])
{
  int next_option;
  char* output;
  char* input;
  char color = 47;

  /**
   * kisa parametler burda tanimli
   *  ardindan parametre alanlar : ile bitiyor
   *  orn: o: bir parametre aliyor b almiyor
   *  -o kelebek yada -b gibi
   */
  const char* const short_options = "hbro:i:";

  /**
   * Burdada uzun hallerini tanimliyoruz.
   *  beraberinde kisa karsiliklarida var.
   */
  const struct option long_options[] = {
    {"help",   no_argument, 0, 'h'},
    {"blue",   no_argument, 0, 'b'},
    {"red",    no_argument, 0, 'r'},
    {"input",  required_argument, 0, 'i'},
    {"output", required_argument, 0, 'o'}
  };

  /**
   * Burda sirayla verilen argumalari aliyoruz
   */
  do {
    next_option = getopt_long(argc,
			      argv,
			      short_options,
			      long_options,
			      NULL);
    switch(next_option) {
    case 'h': // -h or --help
      print_usage();
      return 0;
      break;

    case 'o': // -o or --or
      output = optarg;
      break;

    case 'i': // -i or --i
      input = optarg;
      break;

    case 'b': // -b or --blue
      color = 44;
      break;

    case 'r': // -r or --red
      color = 41;
      break;

    case -1:
      break;

    default:
      abort();
    }
  } while (next_option != -1);

  printf("%c[%d;%dmInput : %s%c[%dm\n", 27, 1, color, input, 27, 0);
  printf("%c[%d;%dmOutput: %s%c[%dm\n", 27, 1, color, output, 27, 0);


  return 0;
}

int print_usage ( void ) {
  printf("   --help   or -h for help\n"
	 "   --output or -o for output\n"
	 "   --input  or -i for input\n"
	 "   --blue   or -b for blue output\n"
	 "   --red    or -r for red output\n");
  return 0;
}

Örnek