Winsock, błąd 10038

0

Witam,
podczas odbierania wiadomości przez aplikację wyskakuje błąd 10038, według MSDN działam na nie-socket. Wydaje mi się, że jednak wszystko dobrze jest zrobione, może ktoś z Was spotkał się z podobnym problemem? :)

Z góry dzięki za pomoc.

Kod odbierania:

SOCKET client = INVALID_SOCKET;
if (client = accept(sock, NULL, NULL) != INVALID_SOCKET)
{
	std::cout << "\n>> New user connected!";

	char* msg = NULL;				
	bool bDone = false;
	while (!bDone)
	{
		if (recv(client, msg, BUFOR, NULL) > 0) 
		{
	        	std::cout << "\nmessage: " << msg;
			bDone = true;
		}else std::cout << "\nerror: " << WSAGetLastError();
			Sleep(1000);
	}
}
closesocket(client);	
0

eee a gdzie masz wywołanie socket()?

0
Shalom napisał(a)

eee a gdzie masz wywołanie socket()?

dla clienta jest tylko to:

SOCKET client = INVALID_SOCKET;

dla serwera (sock) nie zamieściłem, ale jest:

SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
0

No super, ale w takim razie ustawiasz sobie klienckiego socketa na jakąś stałą INVALID_SOCKET a potem próbujesz na tym sockecie jakieś dziwne rzeczy zrobić. accept() to funkcja po stronie serwera. Klient powinien sobie sam zrobić socketa z informacjami na temat serwera. Jak ty sobie to w ogóle wyobrażasz? Że ten klient to się jakoś magicznie połączy z serwerem bez informacji na temat jego adresu? o_O

Po stronie klienta robisz zwykle:

  • socket() + [connect() dla TCP] + send()/sendto() + recv()/recvfrom()
    Po stronie serwera:
  • socket() + bind() + [listen() + accept() dla TCP] + send()/sendto() + recv()/recvfrom()
0

Kod źródłowy (fragment), który podałem to kod po stronie serwera, który ma tylko odebrać jakieś dane. Klient to osobna aplikacja. Wszystko łączy się dobrze, klient wysyła też dane przy pomocy funkcji send() i niby je wysyła, ale nie jestem w stanie odebrać ich na serwerze. Nie podałem całego kodu programu bo chyba mija się to z celem skoro nawiązywanie połączenia działa, a jedynym problemem jest odbiór danych :)

Oto cały kod po stronie serwera:

 
#define IP "127.0.0.1"
#define PORT 5010
#define USERS 10
#define BUFOR 1024

int main()
{
	WSAData wsaData;
	
	if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
	{
		std::cout << "\n>> WSAStartup error!";
		_getch();
		return(1);
	}
	
	SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	SOCKADDR_IN saddr;
	
	saddr.sin_addr.S_un.S_addr = inet_addr(IP);
	saddr.sin_family = AF_INET;
	saddr.sin_port = htons(PORT);
	
	if (bind(sock, (sockaddr*) &saddr, sizeof(saddr)) == 0)
	{
		std::cout << "\n>> Server started!";
		if (listen(sock, USERS) == 0)
		{
			std::cout << "\n>> Listening started!";	
			SOCKET client = INVALID_SOCKET;
			if (client = accept(sock, NULL, NULL) != INVALID_SOCKET)
			{
				std::cout << "\n>> New user connected!";
				char* msg = NULL;
				
				bool bDone = false;
				while (!bDone)
				{
					if (recv(client, msg, BUFOR, NULL) > 0) 
					{
						std::cout << "\nmessage: " << msg;
						bDone = true;
					}else std::cout << "\nerror: " << WSAGetLastError();
					Sleep(1000);
				}
			}
			closesocket(client);	
		}
		else
		{
			std::cout << "\n>> Listening error:\n" << WSAGetLastError();
			_getch();
			return(1);
		}
	}
	else
	{
		std::cout << "\n>> Server start-up error:\n" << WSAGetLastError();
		_getch();
		return(1);
	}
	
	closesocket(sock);	
	WSACleanup();	
	_getch();
	return(0);
}

EDIT:

qwe napisał(a)

http://cpp0x.pl/kursy/Kurs-WinSock-C++/271

Nie widzę różnicy między tym, a moim kodem. Dalej ten sam irytujący błąd...

0

Ok jeśli chodzi o błędy to:
msg jest wskaźnikiem na NULL a potem do niego wczytujesz, a to bardzo nie ładnie... Wrzuć tam tablicę o rozmiarze BUFOR (niefortunna nazwa, powinno być BUFFER_SIZE jakieś...)

0
Shalom napisał(a)

Ok jeśli chodzi o błędy to:
msg jest wskaźnikiem na NULL a potem do niego wczytujesz, a to bardzo nie ładnie... Wrzuć tam tablicę o rozmiarze BUFOR (niefortunna nazwa, powinno być BUFFER_SIZE jakieś...)

Zrobione, ale ciągle nie działa. Dalej ten sam błąd 10038.

0

A czym jest SOCKET? Nie mam za dużego doświadczenia z winsock, ale unixowe sockety jako identyfikatory mają inty i z tego co widzę w tym kursie winsocka tam też sa inty...

0

Nie ma różnicy jak zmienię z SOCKET na int. Czyli gniazda to liczby całkowite... Znalazłem jeszcze na jednym forum, że to błąd 10038 może być spowodowany problemami z komputerem. Zaraz skompiluję oba programy w RELEASE i spróbuję odpalić na laptopie :)

EDIT:
Na laptopie to samo czyli problem na 100% leży w kodzie.

EDIT2:
Zamiana ról aplikacji (serwer - wysyła, klient - odbiera) też nie pomogła.
Chyba zaraz wezmę, usunę projekty i jeszcze raz napiszę wszystko :)

0

Rozwiązałem problem!

była nim ta instrukcja if:

 
if (client = accept(sock, NULL, NULL) != INVALID_SOCKET)

zamieniłem ją na:

 
SOCKET client = INVALID_SOCKET;
client = accept(sock, NULL, NULL);
if (client != INVALID_SOCKET)
//dalszy kod

i wszystko pięknie działa. Dziękuję wszystkim za pomoc :)

0

No tak, nawiasy i kolejność operatorów... To przypisanie powodowało przypisanie do client 0 albo 1 a nie wyniku accept ;]

0
Shalom napisał(a)

No tak, nawiasy i kolejność operatorów... To przypisanie powodowało przypisanie do client 0 albo 1 a nie wyniku accept ;]

Dokładnie. Uff, ale niektóre błędy potrafią być upierdliwe :)

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