Soket TCP di c

Saya mencoba menulis antarmuka soket TCP untuk program saya dan saya mengalami kesalahan Accept() (menurut saya). Untuk ini saya telah membuat beberapa kode pengujian yang diringkas.
Pertama saya melakukan sedikit pengaturan

int server_socket = 0;
server_socket = socket(AF_INET, SOCK_STREAM, 0);

int accepted_connection = 0;

struct sockaddr_in server_address;
server_address.sin_port = htons(9001);
server_address.sin_family = AF_INET;
server_address.sin_addr.s_addr = INADDR_ANY;

struct sockaddr_in client_address;
client_address.sin_port = 0;
client_address.sin_family = AF_INET;

char * server_socket_read_buffer[100] = {0};
int server_socket_read_length = 0;

Semua hal yang cukup sederhana. Alokasikan saja beberapa variabel. Selanjutnya saya mengikat dan mendengarkan

if (bind(server_socket,(struct sockaddr *)&server_address, sizeof(server_address)) < 0)
{
    perror("Bind() on server_socket has failed\n");
}

if (listen(server_socket, 10) < 0)
{
    perror("Listen() on server_socket has failed\n");
}

Berikutnya adalah bagian di mana saya yakin saya mempunyai masalah

printf("Attempting accept!\n");
if (accepted_connection = accept(server_socket, (struct sockaddr *)NULL, NULL) < 0)
{
    perror("Accept failed\n");
}
sleep(10);
if (server_socket_read_length = read(accepted_connection, &server_socket_read_buffer, server_socket_read_length) < 0)
{
    perror("Read failed\n");
}
printf("Read %d bytes from socket\n", server_socket_read_length);
for (int i = 0; i<server_socket_read_length;i++)
{
    printf("%x\n",server_socket_read_buffer[i]);
}

Ini dikompilasi dan dijalankan. Ketika saya menggunakan nc dengan perintah 'nc 127.0.0.1 9001' saya mendapatkan koneksi, tetapi tidak ada data yang dibaca. Khususnya saya mendapatkan 0 byte data. Saya pikir ini mungkin disebabkan oleh NULL di baris penerimaan, tetapi mengubahnya menjadi struct dan panjangnya yang tepat mencegah kode saya dikompilasi.

Jika ada yang bisa menjelaskan kesalahan saya, saya akan sangat berterima kasih.


person Darakian    schedule 06.07.2015    source sumber
comment
apakah Anda menggunakan mesin yang memerlukan htons()? itu pertukaran byte, dan Anda mungkin mengatur port 0x2923 (10531) alih-alih 0x2329 (9001).   -  person Marc B    schedule 06.07.2015
comment
Anda harus selalu menggunakan htons() pada nilai konstan saat mengatur kolom sin_port. Pada mesin little-endian, byte akan dibalik, sedangkan pada mesin big-endian tidak boleh dioperasikan.   -  person dbush    schedule 06.07.2015


Jawaban (3)


Ada beberapa kesalahan:

  1. INADDR_ANY dalam urutan byte host dan perlu dikonversi ke jaringan seperti htonl(INADDR_ANY). Tapi itu tidak masalah karena konstanta INADDR_ANY didefinisikan sebagai 0.

  2. Ini

    char * server_socket_read_buffer[100]
    

    seharusnya

    char server_socket_read_buffer[100]
    
  3. Ini

    read(accepted_connection, &server_socket_read_buffer, server_socket_read_length)
    

    seharusnya

    read(accepted_connection, server_socket_read_buffer, sizeof server_socket_read_buffer)
    
person Maxim Egorushkin    schedule 06.07.2015
comment
Saya telah melakukan perubahan yang Anda sarankan dan sepertinya program memblokir jalur baca. Saya telah mengirim lebih dari 100 byte data. Saya tidak dapat menemukan apa pun di halaman manual di read() tentang fungsi pemblokiran. Pikiran? - person Darakian; 06.07.2015
comment
@Darakian Mengapa sleep ada di sana? - person David Schwartz; 06.07.2015
comment
@DavidSchwartz Tidak lagi. Tidur itu ada di sana untuk memastikan saya punya cukup waktu untuk menghancurkan keyboard saya di terminal lain untuk mengirim data. - person Darakian; 06.07.2015
comment
@Darakian Tes dengan echo abc | nc 127.0.0.1 9001. Dan posting kode lengkapnya jika tidak berhasil. - person Maxim Egorushkin; 07.07.2015

Anda meneruskan server_socket_read_length = 0 yang menyebabkan panjang baca maksimum nol. Lewati ukuran buffer. Deklarasi server_socket_read_buffer juga salah. Mungkin Anda harus mengalokasikan buffer yang lebih besar (seperti 4KB) di heap.

Hapus juga tidurnya.

Sisanya mungkin berfungsi karena nc memperoleh koneksi dan Anda dapat menerima dan membaca tanpa kesalahan.

person usr    schedule 06.07.2015
comment
Dan kemudian saya merasa bodoh. Terima kasih telah menunjukkan panjang nol kepada saya. Masalah ini belum terselesaikan sepenuhnya, namun ini membantu. - person Darakian; 06.07.2015

Jadi setelah berjuang lebih keras, saya menemukan jawaban akhir saya. Blok

    if (accepted_connection = accept(server_socket, (struct sockaddr *)NULL, NULL) < 0)
    {
    //code
    }

Tidak berhasil. Bacaan saya nanti diblokir karena koneksi_yang diterima bukan soket yang valid. Mengubah menjadi

    (accepted_connection = accept(server_socket, (struct sockaddr *)NULL, NULL);
    if accepted_connection < 0)
    {
    //code
    }

menyelesaikan masalah saya. Sejauh yang saya dapat kumpulkan, deskriptor file tidak dibuat sejalan dengan if() dan membaca data dari bilangan bulat tidak terlalu membantu.
Terima kasih atas masukan semuanya.

person Darakian    schedule 06.07.2015