Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/140.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 客户端-服务器程序,使用TCP将消息从客户端发送到服务器时出现问题_C++_C_Sockets_Network Programming - Fatal编程技术网

C++ 客户端-服务器程序,使用TCP将消息从客户端发送到服务器时出现问题

C++ 客户端-服务器程序,使用TCP将消息从客户端发送到服务器时出现问题,c++,c,sockets,network-programming,C++,C,Sockets,Network Programming,我有一个小程序,从服务器和客户端发送和接收数据,反之亦然。 一切正常,但我看不到收到的消息的两面,它总是0字节。它没有给出任何编译错误,但是没有按照我想要的方式工作。 你能看看这个吗,我做错了什么? 谢谢 //客户 #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <string.h> #include <time.h> #include <

我有一个小程序,从服务器和客户端发送和接收数据,反之亦然。 一切正常,但我看不到收到的消息的两面,它总是0字节。它没有给出任何编译错误,但是没有按照我想要的方式工作。 你能看看这个吗,我做错了什么? 谢谢

//客户

#include <stdio.h>
#include <unistd.h> 
#include <stdlib.h> 
#include <string.h>
#include <time.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <arpa/inet.h>

int main(int argc, char* argv[])
{
    int sockfd;

    struct addrinfo hints, *servinfo, *p;
    int rv;
    int numbytes;
    char* hostname = "localhost";
    char* server = "localhost";

    memset(&hints, 0, sizeof(hints));
    hints.ai_family = AF_INET;
    hints.ai_socktype = SOCK_STREAM;
    if ((rv = getaddrinfo(hostname, "5000", &hints, &servinfo)) != 0)
    {
        fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
        return 0;
    }


    // loop through all the results and make a socket
    for(p = servinfo; p != NULL; p = p->ai_next) 
    {
        if ((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) 
        {
            perror("client: socket");
            continue;
        }

        if (connect(sockfd, p->ai_addr, p->ai_addrlen) == -1) 
        {
            close(sockfd);
            perror("client: connect");
            continue;
        }
        break;
    }
    if (p == NULL) 
    {
        fprintf(stderr, "client: failed to bind socket\n");
        return 2;
    }

    char message[] = "hi";
    if ((numbytes = send(sockfd, message, 2, 0)) == -1) 
    {
        perror("client: send");
        exit(1);
    }

    int numbytesRecv;
    char buf[100];
    if ((numbytesRecv = recv(sockfd, buf, 99, 0)) == -1) 
    {
        perror("client: recv");
        exit(1);
    }

    freeaddrinfo(servinfo);
    printf("client: sent %d bytes to %s\n", numbytes, server);
    printf("client: received %d bytes from %s\n", numbytesRecv, server);
    buf[numbytesRecv] = '\0';
    printf("client: message received is %s\n",buf);
    close(sockfd);
    return 0;
}
//输出服务器

./serverTCP 
listener: waiting to recvfrom...
I am here
server: got connection from 127.0.0.1
listener: packet is 0 bytes long
listener: packet contains : 

我已经有一段时间没有完成原始套接字编程了,但我认为您的
recv()
调用有些可疑。IIRC,
recv()
阻塞,直到它读取缓冲区的全部大小或连接关闭。由于两端都没有发送足够的数据来填充缓冲区,并且套接字直到
recv()
调用之后才会关闭,因此我认为客户端/服务器中的一个或两个应该挂起。因为他们没有,两件事中的一件正在发生。要么将套接字配置为非阻塞模式,您需要将其配置为阻塞,要么有东西正在关闭套接字。很抱歉,我不能提供比这更详细的帮助,但希望它能为您指明正确的方向。您可能还需要研究要在套接字上使用的
shutdown()
调用,以便在发送缓冲区中的所有数据之前不会关闭它们。不确定这是否与您的问题有关。

我已经有一段时间没有完成原始套接字编程了,但我认为您的
recv()
调用有些可疑。IIRC,
recv()
阻塞,直到它读取缓冲区的全部大小或连接关闭。由于两端都没有发送足够的数据来填充缓冲区,并且套接字直到
recv()
调用之后才会关闭,因此我认为客户端/服务器中的一个或两个应该挂起。因为他们没有,两件事中的一件正在发生。要么将套接字配置为非阻塞模式,您需要将其配置为阻塞,要么有东西正在关闭套接字。很抱歉,我不能提供比这更详细的帮助,但希望它能为您指明正确的方向。您可能还需要研究要在套接字上使用的
shutdown()
调用,以便在发送缓冲区中的所有数据之前不会关闭它们。不确定这是否与您的问题有关。

编辑:我刚刚在OS X上进行了测试。您的代码适合我。现在,我真的认为你一定有什么东西在消耗你的字节。终止您的进程并执行以下操作:

$netstat-na| grep 5000

看看你有没有听到端口5000的声音。如果是这样,您需要杀死服务器


另外,请确保超级服务器(inetd/xinetd)没有在端口5000上生成处理数据的内容。

编辑:我刚刚在OS X上进行了测试。您的代码适合我。现在,我真的认为你一定有什么东西在消耗你的字节。终止您的进程并执行以下操作:

$netstat-na| grep 5000

看看你有没有听到端口5000的声音。如果是这样,您需要杀死服务器


另外,请确保超级服务器(inetd/xinetd)没有生成用于处理端口5000上的数据的内容。

它看起来像是被咬了一口。尝试设置允许立即发送小数据包


请注意,对于生产代码,您应该在决定禁用Nagle算法之前对其进行评测。

这看起来像是您被攻击了。尝试设置允许立即发送小数据包


请注意,对于生产代码,您应该在决定禁用Nagle算法之前进行评测。

您的问题是服务器中的这一行:

if ((numbytes = recv(new_fd, buf, MAXBUFLEN, 0) == -1))
应该是:

if ((numbytes = recv(new_fd, buf, MAXBUFLEN, 0)) == -1)
这将允许正确分配numbytes,这允许

buf[numbytes] = '\0';
去做你想做的事,让

printf("listener: packet contains : %s\n", buf);
打印你想要的

一视同仁

if ((numbytesSend = send(new_fd, msg, strlen(msg), 0) == -1))

但是这个bug并没有在示例程序中表现出来。

您的问题是服务器中的这一行:

if ((numbytes = recv(new_fd, buf, MAXBUFLEN, 0) == -1))
应该是:

if ((numbytes = recv(new_fd, buf, MAXBUFLEN, 0)) == -1)
这将允许正确分配numbytes,这允许

buf[numbytes] = '\0';
去做你想做的事,让

printf("listener: packet contains : %s\n", buf);
打印你想要的

一视同仁

if ((numbytesSend = send(new_fd, msg, strlen(msg), 0) == -1))

但该错误并未在示例程序中表现出来。

当我尝试使用您的建议进行编译时,我在函数“main”中得到了以下编译错误:serverTCP.c:53:error:“TCP\u NODELAY”未声明(此函数中首次使用)serverTCP.c:53:error:(每个未声明的标识符只报告一次serverTCP.c:53:error:对于它出现在其中的每个函数。)我是否需要使用lsocket.@seg.server.fault以外的任何其他库。@seg.server.fault:您需要包括,如下所述:HTH!当我尝试使用您的建议进行编译时,我会收到以下编译错误:serverTCP.c:在函数“main”中:serverTCP.c:53:错误:“TCP_NODELAY”未声明(首次在此函数中使用)serverTCP.c:53:错误:(每个未声明的标识符只报告一次serverTCP.c:53:error:对于它出现在其中的每个函数。)我是否需要使用lsocket以外的任何其他库。@seg.server.fault:您需要包括,如下所述:HTH!recv()可以在读取缓冲区的全部大小之前返回,即发生短读。但是,返回值为零意味着套接字已关闭。这有点奇怪。我同意应该发生一些阻塞。recv()可以在读取缓冲区的全部大小之前返回,即发生短读。但是,返回值为零意味着套接字已关闭。这有点奇怪。我同意应该发生一些阻塞。