Udp消息服务器c ++,两个客户端之间的通信

时间:2013-06-10 03:14:57

标签: c sockets udp

我通过udp服务器(a-> server-> b)在两个udp客户端之间进行通信时遇到问题。 首先,我将客户端的address_in保存到一个hashmap,然后客户端向客户端发送一些消息。每件事情都是正确的(我记录了通信流程),除了服务器只使用客户端b的地址向当前请求的客户端(客户端a)发送消息。这是我的代码:

private:
        std::map<int, sockaddr_in> ids_clients;
        static int socket;

        static void sig_handler(int signo) {
                if (signo == SIGKILL) {
                        close(socket);
                        printf("stopped\n");
                }
        }

        void monitor() {
                int count;
                socklen_t addr_size = sizeof (sockaddr_in);
                struct sockaddr_in address;
                std::map<int, sockaddr_in>::iterator client_it;
                Buffer buffer;
                Message message;
                while (true) {
                        buffer.reset();
                        if ((count = recvfrom(socket, buffer.getBuffer(), buffer.getCapacity(), MSG_TRUNC, (struct sockaddr *) &address, &addr_size)) == -1) {
                                perror("network error!\n");
                                break;
                        }
                        if (count > message.getHeaderSize()) {
                                message.deserialize(&buffer, count);
                                int id = message.getTag();
                                printf("id: %d\n", id);
                                switch (message.getType()) {
                                        case Message::Type::CONN:
                                        {
                                                //Save client address
                                                printf("SOCK: %d, ID: %d, IP: %s, PORT: %d\n", socket, id, inet_ntoa(address.sin_addr), address.sin_port);
                                                ids_clients[id] = address;
                                                message.setTag(Message::Code::OK);
                                                message.serialize(&buffer);
                                                if (sendto(socket, buffer.getBuffer(), buffer.getSize(), 0, (struct sockaddr *) &address, addr_size) == -1) {
                                                        ids_clients.erase(ids_clients.find(id));
                                                        printf("Authenticated - client: %s:%d: could not response!\n", inet_ntoa(address.sin_addr), ntohs(address.sin_port));
                                                        continue;
                                                }
                                                break;
                                        }
                                        case Message::Type::MEDIA:
                                        {
                                                //Send from current client to the client has id = message.getTag();
                                                printf("SOCK: %d, ID: %d, IP: %s, PORT: %d\n", socket, id, inet_ntoa(address.sin_addr), address.sin_port);
                                                if (message.getChannel() == Message::Channel::SINGLE) {
                                                        client_it = ids_clients.find(id);
                                                        if (client_it != ids_clients.end()) {
                                                                printf("ID: %d, IP: %s, PORT: %d\n", message.getSeqNo(), inet_ntoa(client_it->second.sin_addr), client_it->second.sin_port);
                                                                printf("SOCK: %d, SRC ID:%d, TO ID: %d\n", socket, message.getSeqNo(), id);
                                                                message.serialize(&buffer);
                                                                if (sendto(socket, buffer.getBuffer(), buffer.getSize(), 0, (struct sockaddr *) &(client_it->second), sizeof (client_it->second)) == -1) {
                                                                        ids_clients.erase(client_it);
                                                                        printf("Media package - client: %s:%d: could not reach!\n", inet_ntoa(client_it->second.sin_addr), ntohs(client_it->second.sin_port));
                                                                        continue;
                                                                }
                                                        }
                                                }
                                                break;
                                        }
                                }
                        } else {
                                //echo server
                                sendto(socket, buffer.getBuffer(), count, 0, (struct sockaddr *) &address, addr_size);
                        }
                }
        }
public:

        void start(int port) {
                signal(SIGKILL, sig_handler);
                struct sockaddr_in sin;
                socket = ::socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
                int mps = PGK_MAX_SIZE;
                if (setsockopt(socket, SOL_SOCKET, SO_RCVBUF, &mps, sizeof (mps)) == -1) {
                        perror("SO_RCVBUF\n");
                        exit(EXIT_FAILURE);
                }
                memset(&sin, 0, sizeof (sin));
                sin.sin_family = AF_INET;
                sin.sin_addr.s_addr = INADDR_ANY;
                sin.sin_port = htons(port);
                if (bind(socket, (struct sockaddr *) &sin, sizeof (sin))) {
                        perror("bind()\n");
                        exit(EXIT_FAILURE);
                }
                printf("started: port %d\n", port);
                monitor();
                close(socket);
                printf("stopped\n");
        }
};
int Server::socket;

请帮忙, 谢谢!

1 个答案:

答案 0 :(得分:0)

if (count > message.getHeaderSize()) {

如果这是假的,它不会落到:

//echo server
sendto(socket, buffer.getBuffer(), count, 0, (struct sockaddr *) &address, addr_size);

只是把它发回来了?

我们错过了很多代码。如果您希望有人帮助您,您需要提供一个小型的,自包含的可重现的测试用例。请参阅下面的链接以获取帮助。

http://sscce.org/