Avatar billede alfred Nybegynder
01. maj 2000 - 23:27 Der er 5 kommentarer og
1 løsning

socket fra Java til C

Jeg har lavet et par sockets i henholdsvis C og Java. Når jeg prøver at transportere noget fra c til java går det fint, men når vi prøver den anden vej er det ikke altid vi får det hele med. Faktisk er det mere reglen end undtagelsen at der kun bliver overført en byte.
Jeg tror det er noget med noget allokering af memory eller noget i den stil?

Her er c koden:

På forhånd tak,

#include <sys/types.h>

#inlcude <sys/socket.h>

#include <stdio.h>

#include <netinet/in.h>

#include <arpa/inet.h>

#include <unistd.h>

int main(){

int sockfd;

int len, i;

struct sockaddr_in address;

int result;

char test[] ="" /*= (char*)malloc(500)*/;

char *ch = "Jonas får for lidt";

print f("%s\n", ch);

sockfd = socket(AF_INET, SOCK_STREAM, 0);

address.sin_family =AF_INET;

address.sin_addr.s_addr = inet_addr("172.16.20.72");

address.sin_port = htons(3000);

len = sizeof(address);

result = connect(sockfd, (struct sockaddr *)&address, len);

if(result == 1){

perror("oops:client1");

exit;

}

printf("%s %I\n", "Fildeskriptoren", sockfd);

write(sockfd, ch, 18);



read(sockfd, test, 100);

printf("%s\n", test); //her er der problemer. Skriver kun en byte ud, men nogen gange alt hvad vi sender?

//free(test);

close (sockfd);

exit(0);

}
Avatar billede cmadsen Nybegynder
02. maj 2000 - 08:07 #1
der skal allokers plads til test.

char *test  = malloc(100);

er det der modtages i test altid en NULL termineret streng?

Hvis ikke, så vil printf ikke virke pålideligt.
Avatar billede soepro Nybegynder
02. maj 2000 - 11:01 #2
Hvis du i read(sockfd, test, 100) fast læser 100 bytes, skal du da bare definere test som:

char test[100] = "";

free(test) er så aldrig relevant - den kalder programmets cleanup selv.
Avatar billede baz Nybegynder
02. maj 2000 - 13:02 #3
Der er ingen garanti for at read() giver dig alle data i eet kald. Hvis du vil læse en hel linie afsluttet med "\n" skal du lave en løkke a la:

int nread=0;

while(nread<99) {
  int rc;
  rc=read(sockfd, test+nread, 99-nread);
  if(rc<0) {
    perror("read() failed");
    close(sockfd);
    exit(1);
  }
  if(rc=0) {
    printf("Socket closed by peer\n");
    close(sockfd);
    exit(1);
  }
  nread+=rc;
  test[nread]='\0';
  if(strchr(test, '\n'); {
    /* Got full string */
    break;
  }
}
if(test[nread-1]=='\n')
  printf("Got full string: %s", test);
else
    printf("Got partial string: %s\n",test);
close(sockfd);
exit(0);
Avatar billede alfred Nybegynder
02. maj 2000 - 15:44 #4
Jeg har prøvet at lave en sleep(1); og det virkede umiddelbart fint, men kan jeg være sikker på at det virker hver gang?
Avatar billede baz Nybegynder
02. maj 2000 - 16:12 #5
Nope!

Den eneste måde du kan være sikker på, at det virker hver gang, er ved at blive ved med at kalde read() indtil du har modtaget alle de data, du skal bruge. sleep(1) lapper bare på en fundamentalt forkert løsning. Fejlen kan stadig opstå - det sker bare sjældnere.
Avatar billede soepro Nybegynder
03. maj 2000 - 08:29 #6
Hvor kommer tallet på de 100 fra ??? Er det den "kontrol" struktur gennem hvilken der kommunikeres med Socket'en ??? Eller er det blot/kun dine egne data ???

Uanset hvad, kan jeg ikke forstå at jeg ikke skulle kunne få alt information fra socket'en i et hug, når blot jeg positivt ved hvor lang den er. Er problemet at det ved jeg ikke ?! I såfald ville jeg foreslå en struktur som anvendes i mange ClientAccess API'er, hvor datastrukturen altid starter med 2 byte indeholdende længden af det returnerede svar. På den måde ved jeg at jeg altid kan forvente 2 bytes, og hvis disse to bytes indeholde andet end 0, så ved jeg også hvor mange bytes jeg kan forvente efterfølgende.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester



IT-JOB