【问题标题】:UDP server client c++: sendto, recvfromUDP服务器客户端c++:sendto、recvfrom
【发布时间】:2018-10-29 18:21:01
【问题描述】:

我正在尝试完成一个简单的回显服务器。目标是将消息重复回客户端。服务器和客户端都编译。服务器绑定到 localhost 和端口 8080。客户端有地址、端口和消息。当客户端通过程序到达 sendto 部分时,它会停止并在那里等待。我的目标是将其发送到服务器,然后服务器将其发回。

问题:客户端发送消息,服务器正确接收,但服务器无法返回消息。请帮忙!

服务器端代码:

#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;
}

客户端代码:

#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;
}

【问题讨论】:

  • 呃我有一个简单的问题,IP 地址在哪里,因为我在任何地方都看不到 localhost 或 IP 地址?
  • 而且我什至没有看到使用 connect 的连接??
  • @SkillerDz UDP 是无连接的
  • @user4581301 连接端在哪里?因为我没有看到连接命令?
  • 不需要在客户端绑定socket才能接收吗?

标签: c++ server udp client echo


【解决方案1】:

客户端试图将其消息发送到INADDR_ANY,这是错误的。它需要发送到一个特定的 IP 地址。服务器可以使用INADDR_ANY监听其所有本地IP地址,这很好,但是客户端发送到的IP地址必须是服务器监听的IP地址(或者,如果客户端和服务器在不同的网段,客户端必须发送到到达服务器路由器的 IP,然后必须将消息转发到服务器正在侦听的 IP)。

此外,您在两端对recvfrom()sendto() 的调用缺乏足够的错误处理。特别是,recvfrom()addrlen 参数指定输入时 sockaddr 缓冲区的最大大小,输出时返回存储在 sockaddr 中的对等地址的实际大小。但是您没有初始化作为addrlen 传入的len 变量,因此recvfrom() 可能会失败并出现您无法处理的错误。

尝试类似的方法:

服务器:

#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;
}

客户:

#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;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-09
    • 1970-01-01
    • 2020-06-22
    相关资源
    最近更新 更多