winsock select()ing 运行时错误

发布于 2024-10-05 02:46:31 字数 5330 浏览 1 评论 0原文

我正在尝试找到我之前发布的有关同步聊天消息的问题的解决方案,一位成员向我指出了 select() 函数的方向。我阅读了 Beej 网络指南下的部分,并尝试在windows下编写给出的示例。它编译得很好,但是当我去测试它时,程序崩溃并显示我的错误消息“-选择错误” - 在将端口号输入到程序中后。我不确定如何让它工作,请指教。

服务器.cpp

#include <iostream>
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
using namespace std;
const int winsockver = 2;
int PORT;
int fdmax;
char buffer[80];

int main(void){
    //*********************************************
    fd_set master;
    fd_set temp;
    SOCKET newfd;
    struct sockaddr_in connected_client;
    //*********************************************

    WSADATA wsadata;
    if (WSAStartup(MAKEWORD(winsockver,0),&wsadata) == 0 ){
        cout<<"-Winsock Initialized." << endl;
        cout<<"Enter PORT:";
        cin>> PORT;
        //--------------------------------------------------------------------
        struct sockaddr_in server_info;
        server_info.sin_family = AF_INET;
        server_info.sin_port = htons(PORT);
        server_info.sin_addr.s_addr = INADDR_ANY;

        SOCKET serv_sock = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
        if ( serv_sock != INVALID_SOCKET){
            if ( bind(serv_sock,(sockaddr*)&server_info,sizeof(server_info)) != -1 ){
                char yes = '1';
                if ( setsockopt(serv_sock,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(yes)) != SOCKET_ERROR){
                    cout<<"-Binding Successful." << endl;
                }
            }

            if ( listen(serv_sock,5) != -1 ){
                cout<<"-Listening for incoming connections." << endl;
            }

            FD_SET(serv_sock,&master);
            fdmax = serv_sock; // keeping track of the largers sockfd, at this moment its serv_sock
            //#########################################################
            for(;;){
                temp = master; // copying to temp the master set
                if (select(fdmax+1,&temp,NULL,NULL,NULL) == -1 ){
                    cout<<"-select error." << endl;
                }

                //run through existing connections looking for data to read 
                for (int i = 0; i <= fdmax; i++){
                    if (FD_ISSET(i,&temp)){//we have one
                        if (i == serv_sock){//handle new connections
                            int size =sizeof(connected_client);
                            newfd = accept(serv_sock,(sockaddr*)&connected_client,&size);

                            if ( newfd == -1 ){
                                cout<<"-Accepted an invalid socket from newfd." << endl;
                            }else{//accept has returned a valid socket descriptor and we add it to the master
                                FD_SET(newfd,&master);
                                if (newfd > fdmax ){
                                    fdmax = newfd;
                                }
                                char *connected_ip= inet_ntoa(connected_client.sin_addr);   
                                cout<<"-Select server new connection from " << connected_ip << " " <<  endl;
                            }

                        }else{
                            //handle data from a client
                            int bytes_in;
                            bytes_in = recv(i,buffer,sizeof(buffer),0);
                            if ( bytes_in <= 0 ){
                                if (bytes_in == 0 ){
                                    cout<<"-Connected socket " << i << ",disconnected " << endl;
                                }else{
                                    cout<<"-Socket error." << endl;
                                }
                                closesocket(i);
                                FD_CLR(i,&master); //remove from master set.
                            }else{
                                //we get data from a client
                                for (int j=0; j <= fdmax; j++ ){
                                    //send to everyone
                                    if (FD_ISSET(j,&master)){
                                        //except the listener and ourself
                                        if ( (j != serv_sock) && (j != i) ){
                                            if ( send(j,buffer,sizeof(buffer),0) == -1 ){
                                                cout<<"-Sending error" << endl;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            //#########################################################
        }

        //--------------------------------------------------------------------
    }else{
        cout<<"-Unable to Initialize." << endl;
    }

    if ( WSACleanup() != -1 ){
        cout<<"-Cleanup Successful." << endl;
    }
    return 0;
}

I'm trying to find a solution to a question I posted earlier about synchronizing chat messages, and one member pointed me in the direction of the select() function. I read this section under Beej's Network Guide and tried to write the sample given under windows. It compiles fine but when I go to test it, The program crashes and displays my error message "-Select error"- after inputting the port number into the program. I'm uncertain of how to get this working, please advise.

server.cpp

#include <iostream>
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
using namespace std;
const int winsockver = 2;
int PORT;
int fdmax;
char buffer[80];

int main(void){
    //*********************************************
    fd_set master;
    fd_set temp;
    SOCKET newfd;
    struct sockaddr_in connected_client;
    //*********************************************

    WSADATA wsadata;
    if (WSAStartup(MAKEWORD(winsockver,0),&wsadata) == 0 ){
        cout<<"-Winsock Initialized." << endl;
        cout<<"Enter PORT:";
        cin>> PORT;
        //--------------------------------------------------------------------
        struct sockaddr_in server_info;
        server_info.sin_family = AF_INET;
        server_info.sin_port = htons(PORT);
        server_info.sin_addr.s_addr = INADDR_ANY;

        SOCKET serv_sock = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
        if ( serv_sock != INVALID_SOCKET){
            if ( bind(serv_sock,(sockaddr*)&server_info,sizeof(server_info)) != -1 ){
                char yes = '1';
                if ( setsockopt(serv_sock,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(yes)) != SOCKET_ERROR){
                    cout<<"-Binding Successful." << endl;
                }
            }

            if ( listen(serv_sock,5) != -1 ){
                cout<<"-Listening for incoming connections." << endl;
            }

            FD_SET(serv_sock,&master);
            fdmax = serv_sock; // keeping track of the largers sockfd, at this moment its serv_sock
            //#########################################################
            for(;;){
                temp = master; // copying to temp the master set
                if (select(fdmax+1,&temp,NULL,NULL,NULL) == -1 ){
                    cout<<"-select error." << endl;
                }

                //run through existing connections looking for data to read 
                for (int i = 0; i <= fdmax; i++){
                    if (FD_ISSET(i,&temp)){//we have one
                        if (i == serv_sock){//handle new connections
                            int size =sizeof(connected_client);
                            newfd = accept(serv_sock,(sockaddr*)&connected_client,&size);

                            if ( newfd == -1 ){
                                cout<<"-Accepted an invalid socket from newfd." << endl;
                            }else{//accept has returned a valid socket descriptor and we add it to the master
                                FD_SET(newfd,&master);
                                if (newfd > fdmax ){
                                    fdmax = newfd;
                                }
                                char *connected_ip= inet_ntoa(connected_client.sin_addr);   
                                cout<<"-Select server new connection from " << connected_ip << " " <<  endl;
                            }

                        }else{
                            //handle data from a client
                            int bytes_in;
                            bytes_in = recv(i,buffer,sizeof(buffer),0);
                            if ( bytes_in <= 0 ){
                                if (bytes_in == 0 ){
                                    cout<<"-Connected socket " << i << ",disconnected " << endl;
                                }else{
                                    cout<<"-Socket error." << endl;
                                }
                                closesocket(i);
                                FD_CLR(i,&master); //remove from master set.
                            }else{
                                //we get data from a client
                                for (int j=0; j <= fdmax; j++ ){
                                    //send to everyone
                                    if (FD_ISSET(j,&master)){
                                        //except the listener and ourself
                                        if ( (j != serv_sock) && (j != i) ){
                                            if ( send(j,buffer,sizeof(buffer),0) == -1 ){
                                                cout<<"-Sending error" << endl;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            //#########################################################
        }

        //--------------------------------------------------------------------
    }else{
        cout<<"-Unable to Initialize." << endl;
    }

    if ( WSACleanup() != -1 ){
        cout<<"-Cleanup Successful." << endl;
    }
    return 0;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

梦里人 2024-10-12 02:46:31

您的文件描述符集未正确初始化,因此当您对其调用 FD_SET() 时,它们仍然包含垃圾。

您应该调用 FD_ZERO() 进行初始化在开始使用它们之前:

FD_ZERO(&master);
FD_SET(serv_sock, &master);
fdmax = serv_sock;

Your file descriptor sets are not properly initialized, so they still contain garbage when you call FD_SET() on them.

You should call FD_ZERO() to initialize them before you start using them:

FD_ZERO(&master);
FD_SET(serv_sock, &master);
fdmax = serv_sock;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文