【问题标题】:Udp messaging server c++, communication between two clientsudp消息服务器c ++,两个客户端之间的通信
【发布时间】:2013-06-10 03:14:56
【问题描述】:

两个 udp 客户端通过 udp 服务器(a->server->b)进行通信时遇到问题。 首先,我将客户端的 address_in 保存到哈希图中,然后客户端 a 向客户端 b 发送一些消息。一切都是正确的(我记录了通信流程),除了服务器仅在使用客户端 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;

请帮忙, 谢谢!

【问题讨论】:

  • 提出一个更小的可重现测试用例会让其他人更容易帮助你。这里有很多无关的代码可以让其他人帮助您解决特定问题。
  • 将缩进减少到不超过 4 个空格也会很有帮助
  • 为什么不添加消息的代码,拜托。

标签: c sockets udp


【解决方案1】:
if (count > message.getHeaderSize()) {

如果这是错误的,它不会落入:

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

哪个只是把它发回去?

我们缺少很多代码。如果您希望人们帮助您,您需要提出一个小型、自包含的可复制测试用例。请参阅下面的链接以获取帮助。

http://sscce.org/

【讨论】:

  • 嗨 xaxxon,感谢您的帮助。但我的代码通过 if (count > message.getHeaderSize()) 条件,并记录“SOCK: 3, SRC ID:2, TO ID: 1 id: 1 SOCK: 3, ID: 1, IP: 171.241.192.35, PORT : 1260 ID: 2, IP: 118.102.7.146, PORT: 1477 SOCK: 3, SRC ID:2, TO ID: 1 id: 1 SOCK: 3, ID: 1, IP: 171.241.192.35, PORT: 1260 ID: 2, IP: 118.102.7.146, PORT: 1477 SOCK: 3, SRC ID:2, TO ID: 1" 一切正常,但是消息没有发送到客户端b而是客户端a!!
  • message.getHeaderSize() 是一个常量,只是一个简单的测试所以我没有使用静态字段
  • 请提供问题中的所有日志 - 显示客户端连接的日志 - 并确保将其放在源代码块中以便于阅读
  • 最后 7 点之前我无法回答 :(.
  • 注释掉这一行:printf("id: %d\n", id); 1.连接:int id = message.getTag(); //连接的id printf("SOCK: %d, ID: %d, IP: %s, PORT: %d\n", socket, id, inet_ntoa(address.sin_addr), address.sin_port); 2. 通信:printf("SOCK: %d, SrcID: %d, IP: %s, PORT: %d\n", socket, message.getSeqNo(), inet_ntoa(address.sin_addr), address.sin_port); 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 ->第二个.sin_port); }
猜你喜欢
  • 2021-12-20
  • 2016-02-16
  • 1970-01-01
  • 2019-01-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-21
相关资源
最近更新 更多