Jak można odebrać tekst z serwera do klienta w C++ za pomocą gniazd BSD i UDP?
Mój klient (można w nim wybrać TCP lub UDP):
Klient działa poprawnie z serwerem TCP. Mój serwer UDP:
Klient UDP poprawnie wysyła tekst do serwera UDP, który odbiera ten tekst i wysyła inny tekst do klienta. Klient jednak poprawnie tekstu od serwera nie odbiera i wyświetla błąd "recvfrom: Resource temporarily unavailable'.
Jak rozwiązać ten problem? Jak odebrać dane od serwera? Proszę o pomoc.
Mój klient (można w nim wybrać TCP lub UDP):
Kod:
#include <iostream> //cin
#include <netdb.h> //hostent
#include <fcntl.h> //fcntl, F_SETFL, O_NONBLOCK
using namespace std;
int main()
{
int sockfd, numbytes;
char buf[200];
struct hostent *he;
struct sockaddr_in their_addr;
char Host[100];
int Port;
cout << "Podaj nazwę hosta: ";
cin >> Host;
cout << "Podaj port hosta: ";
cin >> Port;
bool TCPIsUsed;
cout << "Klient ma wykorzystywać TCP (0) czy UDP (1)? Wpisz 0 (dla TCP) lub 1 (dla UDP): ";
short UDPIsUsed;
cin >> UDPIsUsed;
int SocketType, Protocol;
if (UDPIsUsed == 1)
{
TCPIsUsed = false;
SocketType = SOCK_DGRAM;
Protocol = IPPROTO_UDP;
}
else
{
TCPIsUsed = true;
SocketType = SOCK_STREAM;
Protocol = 0;
}
if ((he=gethostbyname(Host)) == NULL)
{ // get the host info
perror("gethostbyname");
}
if ((sockfd = socket(AF_INET, SocketType, Protocol)) == -1)
{
perror("socket");
}
their_addr.sin_family = AF_INET;
their_addr.sin_port = htons(Port);
if (TCPIsUsed)
{
their_addr.sin_addr = *((struct in_addr *)he->h_addr);
memset(&(their_addr.sin_zero), '\0', 8);
if (connect(sockfd, (struct sockaddr *)&their_addr, sizeof(struct sockaddr)) == -1)
{
perror("connect");
}
}
else
{
their_addr.sin_addr = *((struct in_addr *)he->h_addr_list[0]);
memset(their_addr.sin_zero, '\0', sizeof their_addr.sin_zero);
fcntl(sockfd, F_SETFL, O_NONBLOCK);
}
while(true)
{
cout << "Podaj adres URL: ";
char URL[200];
cin >> URL;
if (TCPIsUsed)
{
if (send(sockfd, URL, strlen(URL), 0) == -1)
{
perror("send");
}
}
else
{
if ((sendto(sockfd, URL, strlen(URL), 0, (struct sockaddr *)&their_addr, sizeof their_addr)) == -1)
{
perror("sendto");
}
}
if (TCPIsUsed)
{
if ((numbytes=recv(sockfd, buf, 119, 0)) == -1)
{
perror("recv");
}
}
else
{
__socklen_t size = sizeof(their_addr);
if ((numbytes = recvfrom(sockfd, URL, 119, 0 , (struct sockaddr *)&their_addr, &size) )== -1)
{
perror("recvfrom");
}
}
cout << buf << endl;
}
}
Klient działa poprawnie z serwerem TCP. Mój serwer UDP:
Kod:
#include <iostream> //cout
#include <string.h> //memset
#include <unistd.h> //fork
#include <sys/wait.h>
#include <arpa/inet.h> //SOCK_STREAM, SOL_SOCKET, SO_REUSEADDR
#include <stdio.h> //perror, printf
#include <signal.h> //sigaction, SA_RESTART
using namespace std;
#define BUFLEN 512
#define NPACK 10
#define PORT 9930
void diep(char *s)
{
perror(s);
exit(1);
}
int main(void)
{
struct sockaddr_in si_me, si_other;
int s, i, slen=sizeof(si_other);
char buf[BUFLEN];
if ((s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))==-1)
diep("socket");
memset((char *) &si_me, 0, sizeof(si_me));
si_me.sin_family = AF_INET;
si_me.sin_port = htons(PORT);
si_me.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(s, (sockaddr*)&si_me, sizeof(si_me))==-1)
diep("bind");
for (i=0; i<NPACK; i++) {
if (recvfrom(s, buf, 20, 0, (sockaddr*) &si_other, (socklen_t*) &slen)==-1)
diep("recvfrom()");
printf("Received packet from %s:%d\nData: %s\n\n",
inet_ntoa(si_other.sin_addr), ntohs(si_other.sin_port), buf);
printf("Odebrano: %s\n",buf);
(...)
printf("Wysyłanie: %s\n",buffer);
if (sendto(s, buffer, strlen(buffer), 0, (sockaddr*) &si_other, slen) == -1)
{
perror("send");
}
}
close(s);
return 0;
}
Klient UDP poprawnie wysyła tekst do serwera UDP, który odbiera ten tekst i wysyła inny tekst do klienta. Klient jednak poprawnie tekstu od serwera nie odbiera i wyświetla błąd "recvfrom: Resource temporarily unavailable'.
Jak rozwiązać ten problem? Jak odebrać dane od serwera? Proszę o pomoc.