Skocz do zawartości

[C/Java]Problem z WinSock


adC

Polecane posty

Witam

 

Mam następujący problem, przy próbie wysłania prostego strumienia danych (int lub string), od klienta(java) do serwera©. Serwer nie odbiera tych danych - jest to albo 0 dla wysyłanego int -a albo null dla Stringa. Jak poprawić poniższe kody, aby Klient wysyłał to co ja chce ??

 

Klient(Java)

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

#define DEFAULT_PORT 1239
#define DEFAULT_BUFFER 4096
#define MAXDATASIZE     200

DWORD WINAPI ClientThread(LPVOID lpParam)
{
   SOCKET sock = (SOCKET)lpParam;
   char szBuf[DEFAULT_BUFFER];

int ia =100;

int odba,wys,i,j;
while(1){

    printf("\n  ODBIERAM \n\n");
   int numbytes;
   char* buf[MAXDATASIZE];

       if ((numbytes=recv(sock, buf, sizeof(buf), 0)) == -1) {
           perror("recv");
           exit(1);

       }


//int cos = 0;
//cos = atoi(buf);

       printf("Received: %s",buf);

}

return 0;
}


int main()
{
   WSADATA wsd;
   SOCKET sListen,sClient;
   int iAddrSize;
   HANDLE hThread;
   DWORD dwThreadID;
   struct sockaddr_in local, client;
   struct hostent *host = NULL;


if (WSAStartup(MAKEWORD(2,2), &wsd) != 0)
{
   printf("Blad Winsock 2.2!\n");
   return 1;
}

sListen = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
if (sListen == SOCKET_ERROR)
{
   printf("Blad socket(): %d\n", WSAGetLastError());
   return 1;
}

local.sin_addr.s_addr = htonl(INADDR_ANY);
local.sin_family = AF_INET;
local.sin_port = htons(DEFAULT_PORT);
if (bind(sListen, (struct sockaddr *)&local, sizeof(local)) == SOCKET_ERROR)
{
   printf("Blad bind(): %d\n", WSAGetLastError());
   return 1;
}

host = gethostbyname("localhost");
if (host == NULL)
{
   printf("Nie udalo sie wydobyc nazwy serwera\n");
   return 1;
}

listen(sListen, 8);
printf("SERWER NASLUCHUJE\n");
printf("Adres: %s, port: %d\n", host->h_name, DEFAULT_PORT);

while (1)
{
   iAddrSize = sizeof(client);

   sClient = accept(sListen, (struct sockaddr *)&client, &iAddrSize);
   if (sClient == INVALID_SOCKET)
   {
       printf("Blad funkcji accept(): %d\n", WSAGetLastError());
       return 1;
   }
   printf("Zaakceptowano polaczenie: serwer %s, port %d\n",
       inet_ntoa(client.sin_addr), ntohs(client.sin_port));

hThread = CreateThread(NULL, 0, ClientThread,
       (LPVOID)sClient, 0, &dwThreadID);

   if (hThread == NULL)
   {
       printf("Blad funkcji CreateThread(): %d\n", WSAGetLastError());
       return 1;
   }
   CloseHandle(hThread);
}
closesocket(sListen);

WSACleanup();
return 0;
}

 

Server ©

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

#define DEFAULT_PORT 1239
#define DEFAULT_BUFFER 4096
#define MAXDATASIZE     200

DWORD WINAPI ClientThread(LPVOID lpParam)
{
   SOCKET sock = (SOCKET)lpParam;
   char szBuf[DEFAULT_BUFFER];

int ia =100;

int odba,wys,i,j;
while(1){

    printf("\n  ODBIERAM \n\n");
   int numbytes;
   char* buf[MAXDATASIZE];

       if ((numbytes=recv(sock, buf, sizeof(buf), 0)) == -1) {
           perror("recv");
           exit(1);

       }


//int cos = 0;
//cos = atoi(buf);

       printf("Received: %s",buf);

}

return 0;
}


int main()
{
   WSADATA wsd;
   SOCKET sListen,sClient;
   int iAddrSize;
   HANDLE hThread;
   DWORD dwThreadID;
   struct sockaddr_in local, client;
   struct hostent *host = NULL;


if (WSAStartup(MAKEWORD(2,2), &wsd) != 0)
{
   printf("Blad Winsock 2.2!\n");
   return 1;
}

sListen = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
if (sListen == SOCKET_ERROR)
{
   printf("Blad socket(): %d\n", WSAGetLastError());
   return 1;
}

local.sin_addr.s_addr = htonl(INADDR_ANY);
local.sin_family = AF_INET;
local.sin_port = htons(DEFAULT_PORT);
if (bind(sListen, (struct sockaddr *)&local, sizeof(local)) == SOCKET_ERROR)
{
   printf("Blad bind(): %d\n", WSAGetLastError());
   return 1;
}

host = gethostbyname("localhost");
if (host == NULL)
{
   printf("Nie udalo sie wydobyc nazwy serwera\n");
   return 1;
}

listen(sListen, 8);
printf("SERWER NASLUCHUJE\n");
printf("Adres: %s, port: %d\n", host->h_name, DEFAULT_PORT);

while (1)
{
   iAddrSize = sizeof(client);

   sClient = accept(sListen, (struct sockaddr *)&client, &iAddrSize);
   if (sClient == INVALID_SOCKET)
   {
       printf("Blad funkcji accept(): %d\n", WSAGetLastError());
       return 1;
   }
   printf("Zaakceptowano polaczenie: serwer %s, port %d\n",
       inet_ntoa(client.sin_addr), ntohs(client.sin_port));

hThread = CreateThread(NULL, 0, ClientThread,
       (LPVOID)sClient, 0, &dwThreadID);

   if (hThread == NULL)
   {
       printf("Blad funkcji CreateThread(): %d\n", WSAGetLastError());
       return 1;
   }
   CloseHandle(hThread);
}
closesocket(sListen);

WSACleanup();
return 0;
}

Link do komentarza
Udostępnij na innych stronach

Kodu servera nie przegladalem, ale nie udaje ci sie wyslac nic bo w javie czytasz a nie zapisujesz. Zerknij z ktorego strumienia korzystasz i czy piszesz do niego czy czytasz ;)

 

wiem , wiem :rolleyes:

 

odrzcilem mozliwosc pisania tej aplikacji w Javie, jednak jeszcze za bardzo socket-ow nie rozumiem. Napisalem klienta w c i tu tez napotkalem bląd:

int wysylany jest bez problemu, ale mam problem z wysylka stringa (char *) w miejscu gdzie ma byc napis(nazwa gracza w tym przypadku) jest puste miejsce, dlaczego ?

 

kody:

 

server

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

int port = 4951,buf = 4096;
int bytes_sent,bytes_recv;
char *chars_sent,*chars_recv;
int numbytes;


struct info{

   int jakisint;
   char *nazwa_gracza;
   int jakisint2;
   } dane;

//wątek do komunikacji z klientem
DWORD WINAPI ClientThread(LPVOID lpParam)
{
   SOCKET sock = (SOCKET)lpParam;
   //char szBuf[buf];

while(1)
{
   //dane.nazwa_gracza[numbytes]='';
   //dane.jakisint =0;
   dane.jakisint = 0;
   dane.jakisint2 = 0;
   dane.nazwa_gracza = '';
   char tmp[50];
   bytes_recv = recv(sock,(char*)&dane,sizeof(dane),0);

   printf("\nodebralem dane od klienta... ");
   printf("\nNazwa klienta : %s",dane.nazwa_gracza);
   printf("\nJakis int     : %d",dane.jakisint);
   printf("\nJakis int2    : %d\n",dane.jakisint2);

//    if(dane.nazwa_gracza == NULL){
//        printf("\n\nnazwa gracza ostala utracona, ponawiam probe jej uzyskania\n");
//        bytes_sent = send(sock,"nazwa",6,0);
//    }else{
//        printf("nazwa gracze prawidlowa przesylam potwierdzenie jej otrzymania\n");
//        bytes_sent = send(sock,"ng_ok",6,0);
//    }

//    if(dane.jakisint == 0){
//        printf("jakis int zostal utracony, ponawiam probe jego uzyskania\n");
//        bytes_sent = send(sock,"int",3,0);
//    }else{
//        printf("jakis int prawidlowy przesylam potwierdzenie jego otrzymania\n");
//        bytes_sent = send(sock,"int_ok",6,0);
//    }

   system("pause");

}
return 0;
}


int main()
{
   WSADATA wsd;
   SOCKET sListen,
   sClient;
   int iAddrSize;
   HANDLE hThread;
   DWORD dwThreadID;
   struct sockaddr_in local, client;
   struct hostent *host = NULL;

   //zerowanie struktury



if (WSAStartup(MAKEWORD(2,2), &wsd) != 0)
{
   printf("Bladd ladowania Winsock 2.2!\n");
   return 1;
}


sListen = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
if (sListen == SOCKET_ERROR)
{
   printf("Blad funkcji socket(): %d\n", WSAGetLastError());
   return 1;
}


local.sin_addr.s_addr = htonl(INADDR_ANY);
local.sin_family = AF_INET;
local.sin_port = htons(port);
if (bind(sListen, (struct sockaddr *)&local, sizeof(local)) == SOCKET_ERROR)
{
   printf("Blad funkcji bind(): %d\n", WSAGetLastError());
   return 1;
}

host = gethostbyname("localhost");
if (host == NULL)
{
   printf("Nie udalo sie wydobyc nazwy serwera\n");
   return 1;
}

listen(sListen, 8);
printf("SERWER NASLUCHUJE\n");
printf("Adres: %s, port: %d\n", host->h_name, port);


while (1)
{
   iAddrSize = sizeof(client);
   sClient = accept(sListen, (struct sockaddr *)&client, &iAddrSize);
   if (sClient == INVALID_SOCKET)
   {
       printf("Blad funkcji accept(): %d\n", WSAGetLastError());
       return 1;
   }
   printf("Zaakceptowano polaczenie: serwer %s, port %d\n",
       inet_ntoa(client.sin_addr), ntohs(client.sin_port));

//tworenie nowego wątku
hThread = CreateThread(NULL, 0, ClientThread,
       (LPVOID)sClient, 0, &dwThreadID);
   if (hThread == NULL)
   {
       printf("Blad funkcji CreateThread(): %d\n", WSAGetLastError());
       return 1;
   }
   CloseHandle(hThread);
}
closesocket(sListen);

WSACleanup();
return 0;
}

Link do komentarza
Udostępnij na innych stronach

polecam siasc w javie, bedzie ci duzo prosciej.

napisz sobie server/client w javie od zera. Calosc sprowadzi sie do pisania/czytania ze streama.

na sieci jest 100000 tutoriali o tym

 

a ja własnie nie mam możliwości pisania w Javie, to w załozeniu ma być server pisany pod pewna grę(docelowo dla czterech graczy) i on właśnie musi być pisany w jęyku innym niz Java

Link do komentarza
Udostępnij na innych stronach

Jak na moje oko serwer nic nie dostaje bo masz char* nazwa w rekordzie więc przesyłasz wskaźnik a nie dane. Napisz własną metodę do wysyłania tego string i jego odbioru lub zrób np. char napis[100]; wtedy musisz pilnować aby długość<100

 

aha, prawde mówiąc troche inaczej rozwiązałem ten problem, poproatu tworzę, poza strukturą:

 

char* msg = "jakis tekst"; &,2ł)Zz+gĘkr$ĄltŃ-ąŃĄĄĄ

 

zdaje sobie sprawe, że to dośc łopatologiczne rozwiazanie problemu, ale stringiem, czy tam tablica char-ów bedzie wysyłane tylko imie gracza, więc sądze że mogę sobie na to pozwolić ;)

 

Mam jezcze jedno pytanie odnośnie socketów w c/c++ : czy jest mozliwe aby serwer wykrył odejscie klienta od gry i żey klient wykrył np.: wyłączenie serwwera itp.

Link do komentarza
Udostępnij na innych stronach

a czy sizeof(char*) = 4 ?

 

 

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

int main()
{
   char* t= "czesc";
   int i,j = 0;
   i = sizeof(t);
   j = strlen(t);
   printf("%d,   %d",i,j);
   return 0;
}%Ź2)Ąq,nwÓ4N5{Ś{4Ó^l>ŹąĄĘ'ś){(uę^fi'ę'ŹŻ,y'!Źj|śŁ      mÓĄ.^h{&ĘiŻ<j9j3&łjx(ŚŚ-zęsz6jćjzŚ      int bytes_sent = 0;&+Zs6Ź+2k:n'})HY
][H[
HOH
^[      ][Y[ZHHX[[YI][ĘN]
RY[JNB

 

powinno dac rade, jeszcze pomysle nad jakims lepszym rozwiazaniem

Link do komentarza
Udostępnij na innych stronach

jak można wysłać/odebrać

 

Pozdrawiam! :P

Gdy jest ujemna oznacza błąd, tak jest w javie i wtedy klienta się rozłączył. Z tego powodu nie jestem przekonany aby testowanie czy ilość bajtów==0 było dobre, nie wiem jak jest w docu, ale bardziej mnie przekonuje, że ==-1. Najlepiej sprawdzić na dwóch komputerach i odłączyć jeden z sieci i zobaczyć co send zwróci. Gorzej jeśli tak jak u mnie na uczelni sieć jest buforowana (pewnie jest naukowe słowo na to):D

Baza tysięcy lotnisk: http://airportsbase.com

Link do komentarza
Udostępnij na innych stronach

Gdy jest ujemna oznacza błąd, tak jest w javie i wtedy klienta się rozłączył. Z tego powodu nie jestem przekonany aby testowanie czy ilość bajtów==0 było dobre, nie wiem jak jest w docu, ale bardziej mnie przekonuje, że ==-1. Najlepiej sprawdzić na dwóch komputerach i odłączyć jeden z sieci i zobaczyć co send zwróci. Gorzej jeśli tak jak u mnie na uczelni sieć jest buforowana (pewnie jest naukowe słowo na to):D

 

I właśnie chyba tak zrobie, nic innego raczej juz nie wymyśle

 

Wielkie dzięki za pomoc ;)

Link do komentarza
Udostępnij na innych stronach

podczas tworzenie mojej aplikacji pojawił się kolejny problem, otóż gdy, próbuje wysłać tablice int-ową znajdujacą stworzona na podst. struktury

 

 typedef struct{
int pozycja;
}Dane;

Dane dane[6][4];
&[mibq-r^O|}]Ż{tÓ]4nu~=mź|ó]tĘzó{;Ś   send(soc,(char*)&dane,sizeof(dane),0);

 

dostaje taka oto tablice

 

KOD75 1 76 2 50

50 3 98 4 3

3 5 99 6 7

7 7 121 8 27

27 9 26 10 97

97 11 74 12 16632

16632 0 144 0 0

 

a zkoleji gdy probuje ta tablice wyslac int po incie za pomoca for-a to podczas odbioru w polach 6x3 i 6x4 funkcja recv zwraca mi wartosc -1, a poprzednie pola są odebrane poprawnie ??

Link do komentarza
Udostępnij na innych stronach

CYTAT(Toster @ wto, 25 sie 2009 - 21:24) <{POST_SNAPBACK}>

petle powinny byc odpowiednio <6 i <4, to co dajesz w petli przed znakiem '<' powinno odpowiadac temu jak deklarujesz tablice. Te petle wychodza poza zakres.

 

 

ale gdy zrobie tak jak piszesz, to 6 ostatnich komorek tablicy jest błędnych

 

 

Ja bym się bał słać z sizeof(dane) ponieważ nie wiem czy można zaufać, że wszystkie 24 komórki są obok siebie, ale mogę się mylić bo to statyczna tablica. Durgie pytanie to jaki os ma komputer wysyłający i jaki odbierający?

 

wydaje mi sie ze mozna zaufac bo przecież ja badam rozmiar kazdej wysylanej komórki, ja klient i server bede po 2000/xp pracowaly - jesli o to chodzilo :P

Link do komentarza
Udostępnij na innych stronach

skup sie, definiujesz tablice 6x4 = 24 wartosci

przewin ekran do gory i policz ile wyswietlasz liczb.

Operujesz na indexach poza zakresem przez co program moze ci swirowac lacznie z av

jak robisz int d[5] to znaczy ze mozesz uzywac indexow od 0 do 4 a nie od 0 do 5.

Always Dark<br />u1_tt_logo.png banner-1.pngexFabula-banner.pngson_banner_ubersmall.jpg

Link do komentarza
Udostępnij na innych stronach

skup sie, definiujesz tablice 6x4 = 24 wartosci

przewin ekran do gory i policz ile wyswietlasz liczb.

Operujesz na indexach poza zakresem przez co program moze ci swirowac lacznie z av

jak robisz int d[5] to znaczy ze mozesz uzywac indexow od 0 do 4 a nie od 0 do 5.

 

juz zalapalem ;) , ostatni problem i ostatnie pytanie(miejmy taka nadzieje). Tak więc czy jest mozliwa, nie wiem zaa bardzo okreslic, 'optymalizacja' watku tak aby nie zajmowal 50 % CPU ?? Moj wątek

 

DWORD WINAPI pobierzDaneThread(LPVOID lpParam){
   Sleep(300);
   int bytes_recv;
   while(1){
       Sleep(4000);
       if((bytes_recv = recv(socketClient,(char*)&dane,sizeof(dane),0)) == -1){
           std::cout <<"err:: wystapil blad podczas odbioru pakietu";
       }else{
           przyjmijDane();
           }
           Sleep(30000);
       }
   }
}

 

P.S na jakiejs stronie wyczytalem ze pole drugie DWORD cbStack służy do zadeklarowania ile przestrzeni adresowej jest do wykorzystania, zcy tutaj tkwi rozwiazanie mojego problemu?

 

problem juz rozwiazany ;)

Link do komentarza
Udostępnij na innych stronach

Zarchiwizowany

Ten temat jest archiwizowany i nie można dodawać nowych odpowiedzi.

×
×
  • Utwórz nowe...