简体   繁体   中英

UDP server client c++: sendto, recvfrom

I'm trying to complete a simple echo server. The goal is to repeat back the message to the client. The server and client both compile.The server is binded to localhost and port 8080. The client has the address, the port, and the message. When the client goes through the program to the sendto section, it stop and waits there. My goal it to have it sent to the server, and the server to send it back.

Problem: The client is send the message and the server is receiving it correctly but the server is not able to return the message. Please help!

SERVER SIDE CODE:

#include <iostream>
#include <string.h>
#include <fstream>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#define PORT 8080

using namespace std;

int main() {
  int serSockDes, len, readStatus;
  struct sockaddr_in serAddr, cliAddr;
  char buff[1024] = {0};
  char msg[] = "Hello to you too!!!\n";

  //creating a new server socket
  if((serSockDes = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
    perror("socket creation error...\n");
    exit(-1);
  }

  //binding the port to ip and port
  serAddr.sin_family = AF_INET;
  serAddr.sin_port = htons(PORT);
  serAddr.sin_addr.s_addr = INADDR_ANY;

  if((bind(serSockDes, (struct sockaddr*)&serAddr, sizeof(serAddr))) < 0) {
    perror("binding error...\n");
    exit(-1);
  }

  readStatus = recvfrom(serSockDes, buff, 1024, 0, (struct sockaddr*)&cliAddr, (socklen_t*)&len);
  buff[readStatus] = '\0';
  cout<<buff;

  cout<<len;

  sendto(serSockDes, msg, strlen(msg), 0, (struct sockaddr*)&cliAddr, len);

  return 0;
}

CLIENT SIDE CODE:

#include <iostream>
#include <fstream>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#define PORT 8080

using namespace std;

int main(int argc, char** argv) {
  int cliSockDes, readStatus, len;
  struct sockaddr_in serAddr;
  char msg[] = "Hello!!!\n";
  char buff[1024] = {0};

  //create a socket
  if((cliSockDes = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
    perror("socket creation error...\n");
    exit(-1);
  }

  //server socket address
  serAddr.sin_family = AF_INET;
  serAddr.sin_port = htons(PORT);
  serAddr.sin_addr.s_addr = INADDR_ANY;

  sendto(cliSockDes, msg, strlen(msg), 0, (struct sockaddr*)&serAddr, sizeof(serAddr));

  readStatus = recvfrom(cliSockDes, buff, 1024, 0, (struct sockaddr*)&serAddr, (socklen_t*)&len);
  buff[readStatus] = '\0';
  cout<<buff;

  return 0;
}

The client is trying to send its message to INADDR_ANY , which is wrong. It needs to send to a specific IP address instead. The server can listen to all of its local IP addresses using INADDR_ANY , that is fine, but the IP address that the client sends to must be one that the server listens on (or, if the client and server are on different network segments, the client must send to an IP that reaches the server's router, which then must forward the message to an IP that the server is listening on).

Also, your calls to recvfrom() and sendto() on both ends are lacking adequate error handling. In particular, the addrlen parameter of recvfrom() specifies the max size of the sockaddr buffer upon input, and upon output returns the actual size of the peer address stored in the sockaddr . But you are not initializing the len variable that you pass in as the addrlen , so recvfrom() is likely to fail with an error that you do not handle.

Try something more like this instead:

Server:

#include <iostream>
#include <string.h>
#include <fstream>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
using namespace std;

#define PORT 8080

int main() {
  int serSockDes, readStatus;
  struct sockaddr_in serAddr, cliAddr;
  socklen_t cliAddrLen;
  char buff[1024] = {0};
  char msg[] = "Hello to you too!!!\n";

  //creating a new server socket
  if ((serSockDes = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
    perror("socket creation error...\n");
    exit(-1);
  }

  //binding the port to ip and port
  serAddr.sin_family = AF_INET;
  serAddr.sin_port = htons(PORT);
  serAddr.sin_addr.s_addr = INADDR_ANY;

  if ((bind(serSockDes, (struct sockaddr*)&serAddr, sizeof(serAddr))) < 0) {
    perror("binding error...\n");
    close(serSockDes);
    exit(-1);
  }

  cliAddrLen = sizeof(cliAddr);
  readStatus = recvfrom(serSockDes, buff, 1024, 0, (struct sockaddr*)&cliAddr, &cliAddrLen);
  if (readStatus < 0) { 
    perror("reading error...\n");
    close(serSockDes);
    exit(-1);
  }

  cout.write(buff, readStatus);
  cout << endl;

  if (sendto(serSockDes, msg, strlen(msg), 0, (struct sockaddr*)&cliAddr, cliAddrLen)) < 0) { 
    perror("sending error...\n");
    close(serSockDes);
    exit(-1);
  }

  close(serSockDes);
  return 0;
}

Client:

#include <iostream>
#include <fstream>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
using namespace std;

#define PORT 8080

int main(int argc, char** argv) {
  int cliSockDes, readStatus;
  struct sockaddr_in serAddr;
  socklen_t serAddrLen;
  char msg[] = "Hello!!!\n";
  char buff[1024] = {0};

  //create a socket
  if ((cliSockDes = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
    perror("socket creation error...\n");
    exit(-1);
  }

  //server socket address
  serAddr.sin_family = AF_INET;
  serAddr.sin_port = htons(PORT);
  serAddr.sin_addr.s_addr = inet_addr("127.0.0.1");

  if (sendto(cliSockDes, msg, strlen(msg), 0, (struct sockaddr*)&serAddr, sizeof(serAddr)) < 0) {
    perror("sending error...\n");
    close(cliSockDes);
    exit(-1);
  }

  serAddrLen = sizeof(serAddr);
  readStatus = recvfrom(cliSockDes, buff, 1024, 0, (struct sockaddr*)&serAddr, &serAddrLen);
  if (readStatus < 0) {
    perror("reading error...\n");
    close(cliSockDes);
    exit(-1);
  }

  cout.write(buff, readStatus);
  cout << endl;

  close(cliSockDes);
  return 0;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM