套接字编程(同一台计算机上的服务器和客户端)连接错误

时间:2011-04-14 11:48:39

标签: c++ sockets network-programming

我是套接字编程的新手,我有这个客户端尝试连接到同一台计算机上的服务器。但是在绑定或者accept-cause绑定似乎正确但没有输出之后服务器挂起。我知道服务器可以工作,因为另一个客户端可以正常连接,客户端似乎已经这样做了。是什么原因导致服务器看不到此传入连接?我在这里结束了我的智慧。

我还没有习惯在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));
    }

client.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;
    }

1 个答案:

答案 0 :(得分:2)

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

在您的服务器中执行此操作:

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

        for( ; ; )
        {

//继续阅读,直到读取返回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();    
    }

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

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

麻生太郎,在你接受的电话中,你传递了addrlen ......

 int addrlen = sizeof(struct sockaddr);  

我认为这应该是:

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