c++ - 套接字编程(服务器和客户端在同一台计算机上)连接有问题

标签 c++ sockets network-programming

我是套接字编程的新手,我有一个试图连接到同一台计算机上的服务器的客户端。但是服务器在 bind 或 accept 之后卡在那里——因为 bind 似乎是正确的但没有输出。我知道服务器可以正常工作,因为另一个客户端可以很好地连接,而且客户端似乎已经做到了。是什么导致服务器看不到这个传入连接?我已经无计可施了。

而且我不习惯在 Mac 上编程,所以如果我犯了一些愚蠢的错误,非常感谢您的耐心等待。

我的代码如下:

server.cpp

    using namespace std;
    #include<iostream>
    #include <netinet/in.h>
    #include<stdio.h>
    #include<stdlib.h>
    #include<unistd.h>
    #include<sys/types.h>
    #include<sys/socket.h> 
    #include<arpa/inet.h>

    #define PORT 8888
    #define BACKLOG 20
    //#define DEST_IP "127.0.0.1"


    int process_conn_server(int s)
    {
        ssize_t size =0;
        char buffer[1024];

        for( ; ; )
        {
            size = read(s,buffer,1024);
            if(size == 0)
            {
                return 0;
            }
        }
        sprintf(buffer, "%d bytes altogether\n", (int)size);
        write(s, buffer,strlen(buffer)+1);



        return 0;
    }

    int main(int argc,char *argv[])
    {
        //cout<<"?";
        int ss, sc, r, err;
        struct sockaddr_in server_addr;
        struct sockaddr_in client_addr;
        int   opt=1; 
        pid_t pid;

        bzero(&server_addr, sizeof(server_addr));
        server_addr.sin_family = AF_INET;
        server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
        server_addr.sin_port = htons(PORT);

        ss = socket(AF_INET, SOCK_STREAM, 0);
        if(ss<0)
        {
            cout<<"[process infro]socket error"<<endl;
            return -1;
        }
        cout<<"[process infro]socket successful"<<endl;

        r = setsockopt(ss, SOL_SOCKET,SO_REUSEADDR, (void*)&opt,sizeof(opt));
        if (r == -1)
        { 
            perror("setsockopt(listen)"); 
            return 0;
        }
        cout<<"[process infro]sockopt successful"<<endl;

        cout<<"?";
        err = bind(ss, (struct sockaddr*) &server_addr, sizeof( server_addr));
        cout<<"err";
        if(err < 0)
        {
            cout<<"[process infro]bind error"<<endl;
            return -1;
        }
        cout<<"[process infro]bind successful";


        err=listen(ss, BACKLOG);
        if(err <0)
        {
            cout<<"[process infro]listen error"<<endl;
            return -1;
        }
        cout<<"[process infro]lisen successful";

        for( ; ; )
        {
            int addrlen = sizeof(struct sockaddr);

            sc = accept(ss, (struct sockaddr*)&client_addr, (socklen_t *)&addrlen);

            if(sc < 0)
            {
                continue;
            }

            pid =  fork();
            if (pid == 0)
            {
                close(ss);
                process_conn_server(sc);
            }
            else
            {
                close(sc);
            }
        }
        //opt=0; 

        //setsockopt(ss,SOL_SOCKET,SO_REUSEADDR,(void*)&opt,sizeof(len));
    }

客户端.cpp

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

    #define PORT 8888
    #define DEST_IP "127.0.0.1"

    void process_conn_client(int s)
    {
        ssize_t size = 0;
        char buffer[1024];

        //read from the file to be sent
        fstream outfile("programm.txt",ios::in|ios::out);       

        if (outfile.fail())
        {
            printf("[process infro]cannot open the file to be sent\n");
            return ;
        }   
        printf("[process infro]successfully open the file to be sent\n");

        while(!outfile.eof())
        {

            outfile.getline(buffer,1025,'\n');
            write(s,buffer,1024);       
            size = read(s, buffer, 1024);
            if(size = 0)
            {
                return ;
            }
            //write to the server
            write(s,buffer,size);

            //get response from the server
            size=read(s,buffer,1024);
            write(1,buffer,size);

        }
        outfile.close();    //关闭文件
    }

    int main(int argc,char *argv[])
    {
        int s;
        struct sockaddr_in server_addr;
        bzero(&server_addr, sizeof(server_addr));
        server_addr.sin_family = AF_INET;
        server_addr.sin_addr.s_addr = inet_addr(DEST_IP);
        server_addr.sin_port =  htons(PORT);

        s = socket(AF_INET, SOCK_STREAM, 0);
        if(s < 0)
        {
            cout<<"[process infro]socke error"<<endl;
            return -1;
        }
        cout<<"[process infro] socket built successfully\n";



        //inet_pton(AF_INET, argv[1], &server_addr.sin_addr);


        connect(s, (struct sockaddr*)&server_addr, sizeof(struct sockaddr));
        cout<<"[process infor] connected\n";
        process_conn_client(s);

        close(s);

        return 0;
    }

最佳答案

这可能是无关的....但它不适合评论...

在你的服务器中你这样做:

    int process_conn_server(int s)
    {
        ssize_t size =0;
        char buffer[1024];

        for( ; ; )
        {

//继续读直到read返回0

            size = read(s,buffer,1024);
            if(size == 0)
            {
                return 0;
            }
        }
        sprintf(buffer, "%d bytes altogether\n", (int)size);
        write(s, buffer,strlen(buffer)+1);



        return 0;
    }

在你的客户中你这样做:

    void process_conn_client(int s)
    {
        ssize_t size = 0;
        char buffer[1024];

        //read from the file to be sent
        fstream outfile("programm.txt",ios::in|ios::out);       

        if (outfile.fail())
        {
            printf("[process infro]cannot open the file to be sent\n");
            return ;
        }   
        printf("[process infro]successfully open the file to be sent\n");

        while(!outfile.eof())
        {

            outfile.getline(buffer,1025,'\n');

//写入服务器?

            write(s,buffer,1024);       

//从服务器读取?

            size = read(s, buffer, 1024);
            if(size = 0)
            {
                return ;
            }
            //write to the server
            write(s,buffer,size);

            //get response from the server
            size=read(s,buffer,1024);
            write(1,buffer,size);

        }
        outfile.close();    
    }

由于您的变量名称,这有点难以理解,但看起来您的客户端假设您的服务器将针对接收到的每个数据 block 发回响应,但事实并非如此。您的服务器似乎没有将接受的套接字更改为非阻塞,因此它将阻塞读取调用,直到有一些数据要读取(它永远不会得到 0)...

确定它在此之前失败了吗?你有一些示例输出吗?

此外,在您接受的调用中,您传递了 addrlen...

 int addrlen = sizeof(struct sockaddr);  

我认为这应该是:

 int addrlen = sizeof(struct sockaddr_in);   /* sizeof(client_addr) */

关于c++ - 套接字编程(服务器和客户端在同一台计算机上)连接有问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5662731/

相关文章:

c++ - 为什么 StereoSGBM 给出负数和上面的 numberOfDisparities 数

c++ - 在 Win32 中更改文本的字体

performance - 如何衡量服务器代码的性能和TCP RTT?

java - 将字符串写入套接字的输出流

java - 如何在 Java 上同时支持 IPv4 和 IPv6

linux - Java 从 Linux 上的 Socket 中读取字节

c++ - 通过引用捕获异常对象、临时对象、生命周期问题

c++ - 有没有办法在两个 ROS 节点之间有优先级?

java - 是什么导致了java.net.SocketException : Connection reset after closing client?

java - 阻塞网络任务的问题