Komunikacja Java i Ansi C

0

Witam,

Piszę pewną aplikację opartą o interfejs webowy pisany w Javie oraz pewien powiedzmy "automat" napisany w języku C. Automat ten dostaje kod operacji i ew. dane potrzebne do jej wykonania, wykonuje i wysyła odpowiedź.

Kontroler napisany w Javie i automat w C komunikują się po gniazdach TCP jawnym tekstem.

Tutaj moje pytanie. Automat mam już napisany, jak zapewnić obsługę wysyłania jawnego tekstu w obie strony? Zwykłe utworzenie gniazda i wypisanie na wyjscie strina z poziomu javy w moim automacie nie jest odczytywane lub dane są zniekształcone.

Czym różni się obsługa we/wy miedzy Javą a C i jak sobie z tym poradzić?

0

Pokaż kod i sprawdź czy przypadkiem w Javie nie masz innego kodowania znaków, bo w C zapewne piszesz i odbierasz w ASCII.

0

Pokaż jak wysyłasz i odczytujesz te dane. Jesteś pewien że odczytujesz tyle ile wysyłasz? Bo dane moga się podzielić. Jeden recv może nie odebrać wszystkiego.

0

na razie prymitywny kontroler w Javie:

	public static void main(String[] args) throws InterruptedException {
		
		PrintWriter naSerwer = null;
		BufferedReader zSerwera = null;;
		Socket socket = null;
		final int PORT = 5000;
		
		try {
			socket = new Socket("127.0.0.1", PORT);
			naSerwer = new PrintWriter(new OutputStreamWriter( socket.getOutputStream() ),true);
			zSerwera = new BufferedReader( new InputStreamReader( socket.getInputStream()));
			
			DataOutputStream dataOutputStream = null;
			dataOutputStream = new DataOutputStream(socket.getOutputStream());
			
			while(true) {
				dataOutputStream.writeChars("test");
				dataOutputStream.flush();
				Thread.sleep(300);
			}


		} catch (IOException e) {
			e.printStackTrace();
		}
		

	}

Automat w C:

int main() {

    WSADATA wsaData;
    int listenFd;

    if (WSAStartup(MAKEWORD(1,1), &wsaData) == SOCKET_ERROR) {
        printf ("Error initialising WSA.\n");
        return -1;
    }

    int fd_socket;
    struct sockaddr_in my_addr;
	struct sockaddr_in their_addr;
    char yes = 1;

	if( (fd_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) {
		perror("socket");
		exit(1);
	}

    if((setsockopt(fd_socket, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int))) == -1) {
                perror("setsockopt");
                exit(1);
    }

    my_addr.sin_family = AF_INET;
    my_addr.sin_port = htons(MY_PORT);
    my_addr.sin_addr.s_addr = inet_addr(LOCAL_IP);
    memset(&(my_addr.sin_zero), '\0', 8);

	if((bind(fd_socket, (struct sockaddr *)&my_addr, sizeof(my_addr))) == -1) {
		perror("bind");
		exit(1);
	}

	if((listen(fd_socket, BACKLOG)) == -1) {
		perror("listen");
		exit(1);
	}

    size_t sin_size = sizeof(struct sockaddr);
    int socket;

    if((socket = accept(fd_socket, (struct sockaddr *)&their_addr, &sin_size)) == -1) {
			perror("accept");
			exit(1);
    } else {
            printf("Server got connection from: %s, socket: %d\n", inet_ntoa(their_addr.sin_addr), socket);
    }

    char buffor[24];
    size_t buff_size = sizeof(buffor);
    while(1) {
        int bytes = recv(socket, buffor, buff_size, 0);
        if(bytes > 0) {
         //   //dekoduj_komunikat(buffor);
            printf("%s", buffor);
        }
    }

    return 0;
}
1

a

dataOutputStream.write("test".getBytes());

?

1

spróbuj też wyzerować bufor odbiorczy (printf wymaga łańcucha zakończonego 0)

char buffor[24];
    size_t buff_size = sizeof(buffor);
    while(1) {
        memset( buffor, 0, sizeof(buffor) );
        int bytes = recv(socket, buffor, buff_size, 0);
        if(bytes > 0) {
         //   //dekoduj_komunikat(buffor);
            printf("%s", buffor);
        }
    }
0

Działa, dziękuje :)
Przed Twoim postem właśnie dopisałem czyszczenie bufora.
Możesz wyjaśnić użycie getBytes() ?

0

Encodes this String into a sequence of bytes using the platform's default charset, storing the result into a new byte array.

źródło: http://docs.oracle.com/javase/6/docs/api/java/lang/String.html#getBytes()

0

Witam, dalej kontynuuje pracę nad tym projektem.
Teraz napotkałem na problem z komunikacją C --> Java.
Po stronie C wysyłam komunikat zwrotny(char *)
Funkcja do wysyłania wygląda następująco:

 
if(strncmp(kod_operacji, "GKT", KOD_OPERACJI_MAX) == 0) {
        printf("get_ksiazka_table\n");


        if(record_count_ksiazka > 0) {
            int i;
            for(i = 1; i <= record_count_ksiazka; i++) {
            //for(i = 1; i <= 10; i++) {
                struct KSIAZKA ksiazka = get_ksiazka_by_id(i);
                char * message = parse_to_string_ksiazka(ksiazka);
                //char * message = "000;1;Java & XML;Brian Jonh;PWN;";
                write(socket, message, strlen(message), 0);

                printf("message: %s %d\n", message, sizeof(message));
                Sleep(200);
            }
        }


    }

Powyżej do wysyłania używałem również funkcji send() jak i write(), komunikat zostaje wysłany, gorzej już z odebraniem.
Próbowałem tak:

                        BufferedReader in = null;
			in = new BufferedReader(new InputStreamReader(connectionFactory.getConnection().getInputStream()));
			String line;
			while ((line = in.readLine()) != null) {
				  System.out.println("Line: "+line); 
			}

Niestety blokuje się..

próbowałem również tak:

			while(getDataIn().read(bs) != -1) {
				for (byte b:bs) {
		                    // convert byte into character
		                    char c = (char)b;
		                    str = str + c;
		                 }
			}

Funkcja getDataIn() zwraca obiekt DataInputStream.

Nie wytrzymuje już z tym nerwowo, jest ktoś w stanie pomóc?

0

Jak się blokuje to znaczy e wiadomość nie dochodzi. Źle nawiązłeś połączenie.

0

Połączenie jest raczej dobrze nawiązane:

    char buffor[500];
    size_t buff_size = sizeof(buffor);
    if((socket = accept(fd_socket, (struct sockaddr *)&their_addr, &sin_size)) == -1) {
        perror("accept");
        exit(1);
    } else {
        printf("Server got connection from: %s, socket: %d\n", inet_ntoa(their_addr.sin_addr), socket);
    }

    while(1) {
        memset(buffor, '\0', buff_size);
        int bytes = recv(socket, buffor, buff_size, 0);
        if(bytes > 0) {
            dekoduj_komunikat(buffor, socket);
            //printf("\n\%s\n\n", buffor);
            if(strncmp(buffor, "CLOSE", 5) == 0) {
                break;
            }
        }
    }

    close(socket);

 

Pobieram sobie socket i potem trzymam go do odbierania komunikatów, dekodowania ich i wysyłania odpowiedzi. Jak widac przekazuje deskryptor jako argument do funkcji dekoduj_komunikat()

0

No dobra ale ja mówie o połączeniu ze strony javy. Co robi to twoje factory? Poza tym nie widzę nigdzie żebyś z C wysyłał coś to i java nie ma co odebrać.

0

Poradziłem sobie z problemem :)
Połączenie po stronie Javy i C było w porządku. Dodałem taką funkcjonalność, że przed wysłaniem komunikatu wysyłam do Jabvy jego rozmiar a kontroler w Javie ustawia wielkość bufora jaką ma odebrać i ładnie hula. Dzięki!

jakby ktoś potrzebował:
pobranie po stronie Javy:

	public String getData() {
		String str = "";
		byte[] bs = new byte[getBuffSize()];
		try {		
			getDataIn().read(bs);
			for (byte b:bs)
		    {
		           // convert byte into character
		           char c = (char)b;
		           str = str + c;
		      }
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		return str;
	}

	private DataInputStream getDataIn() {
		if(Kontroler.getDataInputStream() == null) {
			try {
				setDataInputStream(new DataInputStream(ConnectionFactory.getConnection().getInputStream()));
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
		return Kontroler.getDataInputStream();
	}

1 użytkowników online, w tym zalogowanych: 0, gości: 1