[C#/C] Klient w C#, serwer linux C. Problem z połączeniem

Piszę aplikacje, serwer na linuxie w C oparty na TCP oraz klienta, którego ma on obsługiwać w C#. Robiłem testy. Napisałem w C klienta, uruchomiłem na innym serwerze i zdalnie połączyłem się z serwerem. Wszystko działa. Potem przetestowałem klienta w C# na gotowym serwerze, który napisałem wcześniej i też wszystko śmigało jak należy. Problem pojawia się gdy próbuję połączyć się z serwerem w C, klientem napisanym w C#. Adres i porty się zgadzają bo testy poszły jak należy. Niestety w komunikacji między systemami klient nie może połączyć się z serwerem, serwer nie widzi klienta. Nie wiem w czym problem. Na wszelki wypadek dorzucam kody.

Serwer:

#include 


/* niezbędna do close() */

#include 


/* da możliwość korzystania ze zmiennych boolowskich */

#include 


/* obsługa błędów perror() */

#include 

/* do exitów */

#include 


/* memset() */

#include 


/* do utworzenia gniazda

 * 1. socket()

 * 2. connect()

 */

#include 

#include 


/* do struktury sockaddr_in */

#include 


/* do funkcji konwertujących adresy IP */

#include 


/* biblioteka wątków */

#include 


/* ----- DEFINICJE STAŁYCH I ZMIENNYCH GLOBALNYCH -----*/


#define SERVER_PORT 16300

#define QUEUE_LEN 100


bool isRunning = true;


//int TCPSocket(unsigned short port);


/* ----- DEFINICJE FUNKCJI I METOD ----- */


int TCPListener(unsigned short port); //tworzenie nasłuchującego gniazda TCP

void* clientService(void *connectionPtr); //funkcja obsługi klienta


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

{

	//gniazdo listenera

	int listenerSocket;


	//struktura adresowa gniazda obsługi klienta i jego wielkość

	struct sockaddr_in clientAddr;

	unsigned int clientLength;


	//gniazdo dla klienta

	int *client;


	//identyfikator utworzonego watku

	pthread_t threadId = 0;


	//utworzenie gniazda listenera

	if ((listenerSocket = TCPListener(SERVER_PORT)) < 0)

	{

		fprintf(stderr, "%s\n", strerror(errno));

		exit(EXIT_FAILURE);

	}

	printf("Utworzono gniazdo nasluchujace...\n");

	printf("Zaczynam nasluchiwac...\n");


	//pętla nieskończona z nasłuchiwaniem i dołączaniem klientów

	while (1)

	{

		client = (int*)malloc(sizeof(int));

		clientLength = sizeof(clientAddr);

		if ((*client = accept(listenerSocket, (struct sockaddr *)&clientAddr, &clientLength)) < 0)

			fprintf(stderr, "%s\n", strerror(errno));

		printf("Przetwarzam klienta %s...\n", inet_ntoa(clientAddr.sin_addr));

		pthread_create(&threadId, 0, &clientService, (void*)client);

		pthread_detach(threadId);

	}

	//zamknięcie gniazda nasłuchującego

	close(listenerSocket);


	return 0;

}

int TCPListener(unsigned short port) 

{

	//deskryptor gniazda do nasłuchiwania

	int listenSocket;


	//struktura adresowa gniazda do nasłuchiwania

	struct sockaddr_in listenSocketAddr;


	//inicjalizacja gniazda nasłuchującego

	if ((listenSocket = socket(PF_INET, SOCK_STREAM, 0)) < 0)

	{

		perror("Nie udalo sie zainicjalizowac gniazda! ");

		return -1;

	}


	//wyczyszczenie struktury - wypełnienie zerami

	memset(&listenSocketAddr, 0, sizeof(listenSocketAddr));


	listenSocketAddr.sin_family = AF_INET;

	listenSocketAddr.sin_addr.s_addr = htonl(INADDR_ANY);

	listenSocketAddr.sin_port = htons(port);


	//przypisanie adresu lokalnego do gniazda

	if (bind(listenSocket, (struct sockaddr *) &listenSocketAddr, sizeof(listenSocketAddr)) < 0)

	{

		perror("Blad podczas przypisywania gniazdu lokalnego adresu! ");

		return -1;

	}

	//otwarcie portu do nasłuchiwania

	if (listen(listenSocket, QUEUE_LEN) < 0)

	{

		perror("Blad podczas nasluchiwania! ");

		return -1;

	}


	return listenSocket;

}

void* clientService(void* connectionPtr)

{

	int *connection = (int*)connectionPtr;


	//struktura adresowa gniazda do nasłuchiwania

	struct sockaddr_in clientAddr;


	socklen_t clientLength = sizeof(clientAddr);


	//wyczyszczenie struktury - wypełnienie zerami

	memset(&clientAddr, 0, sizeof(clientAddr));


	printf("Deskryptor: %d\n", *connection);


	if ((getpeername(*connection, (struct sockaddr *) &clientAddr, &clientLength)) < 0)

	{

		perror("getpeername()");

	}

	printf("Klient: %s\n", inet_ntoa(clientAddr.sin_addr));

	close(*connection);

	free(connection);

	return 0;

}

Klient:

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Windows.Forms;

using System.Net;

using System.Net.Sockets;


namespace PPZClient

{

    public partial class MainForm : Form

    {

        //ustawienie obiektu klienta TCP/IP

        private TcpClient user;


        //ustawienie kodera/dekodera

        private UTF8Encoding code;


        //ustawienie hosta serwera

        private string host;


        //ustawienie portu, na którym nasłuchuje serwer

        private int port;


        private bool isConnected = false;


        public MainForm()

        {

            InitializeComponent();

            user = new TcpClient();

        }


        private void connectBtn_Click(object sender, EventArgs e)

        {

            if (isConnected)

            {

                isConnected = false;

                connectBtn.Text = "Połącz";

            }

            else

            {

                try

                {

                    //user.Connect(textHost.Text, int.Parse(textPort.Text));

                    user.Client.Connect(textHost.Text, int.Parse(textPort.Text));

                    connectBtn.Text = "Rozłącz";

                    isConnected = true;

                }

                catch (Exception exceptionText)

                {

                    MessageBox.Show("Nie udało się utworzyć gniazda z zadanym hostem na zadanym porcie:\n"+exceptionText, "Błąd tworzenia gniazda!", MessageBoxButtons.OK, MessageBoxIcon.Warning);

                }

            }

        }

    }

}

Przerobiłem ten kod, żeby form nie używać, skompilowałem w Mono i się łączy.

Sprawdź ustawienia firewalla, czy komputery się widzą na wzajem prawidłowo.

A nie idzie tego pod Visualem skompilować? Przecież protokół TCP/IP jest taki sam dla wszystkich systemów. Czy gniazdo, gniazdu, w różnych systemach i językach, nie równe?

Może bym spróbował pod visualem, ale ja windowsa nie mam, więc trudno żebym visuala i .neta używał. C# nie znam (za to znam Javę, a C# ma składnię bliską Javie), ale udało mi się na tyle kod przerobić żebym wiedział że się połączył bez żadnych problemów.

Sam protokół jest taki sam, bo to standard, ale format przesyłanych danych może być różny między różnymi platformami. Jak wysyłasz inta, to odebrać musisz jako inta w tym samym formacie, tzn. np. 4-bajtowy, nie inaczej. Struktura 16-bajtowa musi być odebrana i odczytana jako struktura 16-bajtowa. Może z tym jest problem?

Dałeś trochę za mało kodu, bo tylko do samego połączenia, a te nawiązuje.

Rzecz w tym, że jeszcze nie przesyłam nic. Serwer jest bierny. Klient łączy się z serwerem, a to natomiast powoduje obsługę klienta w nowym wątku, która ogranicza się póki co do wyświetlenia odpowiedniego komunikatu na stdout. Niestety gdy kompiluję program w Visualu to żadnego połączenia nie chce nawiązać. Sypie wyjątek, że nie można było się połączyć. Wszystkie zabezpieczenia na czas kolejnego testowania wyłączyłem. Niestety wciąż to samo. Klient nie może osiągnąć hosta serwera.

Jaki konkretnie wyjątek?

Czym kompilujesz kod w C i której wersji VS używasz?

Kod w C kompiluję za pomocą gcc (GCC) 4.6.3 20120306 (Red Hat 4.6.3-2), natomiast Visuala mam w wersji 2010 Ultimate.