【问题标题】:cannot send nor receive data through sockets无法通过套接字发送或接收数据
【发布时间】:2020-02-29 01:05:39
【问题描述】:

我尝试进行简单的服务器-客户端套接字通信,但服务器似乎无法正常工作。每当我发送或接收时都会收到此错误:

非套接字上的套接字操作:非套接字上的套接字操作

奇怪的是,这只会在服务器发送时出现。 客户似乎还好:

//server
#include <iostream>
#include <sys/socket.h>
#include <string.h>
#include <netinet/in.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <arpa/inet.h>

using namespace std;

int main(){
    const int PORT = 5000;
    int serverfd, clientfd, opt=1, n_send, n_recv;
    sockaddr_in server_address, client_address;
    char recvbuf[1024], sendbuf[1024];
    bzero(&server_address , sizeof(server_address));
    inet_pton(AF_INET, "127.0.0.1",&server_address.sin_addr);
    int x = INADDR_ANY;
    server_address.sin_family = AF_INET;
    server_address.sin_port = htons(PORT);

    socklen_t addrSize = sizeof(server_address);

    if((serverfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0){
        perror(strerror(errno));
        exit(EXIT_FAILURE);
    }
    if((setsockopt(serverfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt))) < 0){
        perror(strerror(errno));
        exit(EXIT_FAILURE);
    }
    if((bind(serverfd, (sockaddr*)&server_address, sizeof(server_address)))< 0){
        perror(strerror(errno));
        exit(EXIT_FAILURE);
    }
    if((listen(serverfd, 1))< 0){
        perror(strerror(errno));
        exit(EXIT_FAILURE);
    }
    if((clientfd = accept(serverfd, (sockaddr *)&server_address, (socklen_t*)&addrSize) < 0)){
        perror(strerror(errno));
        exit(EXIT_FAILURE);
    }

    while (true){
        cout << "SAY TO CLIENT: ";
        bzero(sendbuf, sizeof(sendbuf));
        cin >> sendbuf;
        cout << endl;
        send(clientfd, sendbuf, strlen(sendbuf), 0);
        errno = 0;
        bzero(recvbuf, sizeof(recvbuf));
        if((n_recv = recv(clientfd, recvbuf, sizeof(recvbuf), MSG_WAITALL))< 0){
            perror(strerror(errno));
            exit(EXIT_FAILURE);
        }
        cout << recvbuf << endl;
    }

    return 0;
}
//client
#include <iostream>
#include <sys/socket.h>
#include <string.h>
#include <netinet/in.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <arpa/inet.h>

using namespace std;

int main(){
    const int PORT = 5000;
    int sockfd, n_send, n_recv;
    char recvbuf[1024], sendbuf[1024];
    sockaddr_in server_address;
    bzero(&server_address, sizeof(server_address));
    server_address.sin_family= AF_INET;
    server_address.sin_port = htons(PORT);
    inet_pton(AF_INET, "127.0.0.1", &server_address.sin_addr);
    if((sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0){
        perror(strerror(errno));
        exit(EXIT_FAILURE);
    }
    if(connect(sockfd, (sockaddr *) &server_address, sizeof(server_address))<0){
        perror(strerror(errno));
        exit(EXIT_FAILURE);
    }
    while (true){
        if((n_recv = recv(sockfd, recvbuf, sizeof(recvbuf), MSG_WAITALL)) < 0){
            perror(strerror(errno));
            exit(EXIT_FAILURE);
        }
        cout << "Server: " << recvbuf << endl;
        cout << "Say to server: ";
        cin >> sendbuf;
        cout << endl;
        if((n_send = send(sockfd, sendbuf, sizeof(sendbuf), 0)) < 0){
            perror(strerror(errno));
            exit(EXIT_FAILURE);
        }
    }
    return 0;
}

【问题讨论】:

  • 你在哪里得到这个错误?使用调试器后,到目前为止您发现了什么?
  • 通常你传递 perror() 失败函数的 name,而不是错误消息,因为它已经打印出来了......
  • 我从“发送”函数中得到错误。我尝试删除它一秒钟,然后“recv”导致了同样的错误。
  • 为了让您的生活更轻松,您应该学习 C 或 C++。没有单一语言 C/C++;它们是不同的语言。例如,C++ 有类和继承。在 C 中,您可以有一个名为 classprivate 的变量。我建议修改你的语言标签。

标签: c++ c sockets


【解决方案1】:

clientfd 被分配了一个非套接字值。如果我们更改您的if 中的空格:

if((clientfd =
     accept(serverfd, (sockaddr *)&server_address, (socklen_t*)&addrSize) < 0
   )) {
        perror(strerror(errno));
        exit(EXIT_FAILURE);
    }

由于您编写它的方式,检查了accept(可能是有效的套接字)的结果,并将该结果设置为clientFd。请注意,您的括号位置与您的其他行不匹配。

【讨论】:

  • 附带说明,我发现让每一行都做一件事情要容易得多:分配clientfd,然后在if 中检查结果。它可能会完全消除这个错误。
  • 非常感谢!我一定会记住你的笔记
猜你喜欢
  • 2012-02-12
  • 1970-01-01
  • 1970-01-01
  • 2012-06-09
  • 2014-07-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多