工作Qt框架..,需要得到給出requiremets同一臺計算機上的UDP連接。 1服務器。多個客戶
的解決方案我已經在一臺服務器和2個客戶端我的電腦: IP1,IP2,IP3是端口。
我的服務器上IP1聽,端口號9999 我要發送數據(數據包)到服務器,然後服務器需要我的客戶進行迴應。 所以我可以知道客戶端IP地址和客戶端端口號。
客戶端IP地址和端口如何知道服務器?,這是獲取響應回到客戶端所必需的。
注意:我在同一臺PC上運行server,client1和client2。
工作Qt框架..,需要得到給出requiremets同一臺計算機上的UDP連接。 1服務器。多個客戶
的解決方案我已經在一臺服務器和2個客戶端我的電腦: IP1,IP2,IP3是端口。
我的服務器上IP1聽,端口號9999 我要發送數據(數據包)到服務器,然後服務器需要我的客戶進行迴應。 所以我可以知道客戶端IP地址和客戶端端口號。
客戶端IP地址和端口如何知道服務器?,這是獲取響應回到客戶端所必需的。
注意:我在同一臺PC上運行server,client1和client2。
不確定Qt框架,但使用正常的套接字命令bind
到特定的IP和端口。
handle = socket(AF_INET, SOCK_DGRAM, 0);
// my local computer
struct sockaddr_in addr_loc;
memset(&addr_loc, 0, sizeof(addr_loc));
addr_loc.sin_family = AF_INET;
addr_loc.sin_port = htons(localPort);
addr_loc.sin_addr.s_addr = htonl(localAddr);
bind(handle, (struct sockaddr*)&addr_loc, sizeof(addr_loc));
// the remote location
struct sockaddr_in addr_rem;
memset(&addr_rem, 0, sizeof(addr_rem));
addr_rem.sin_family = AF_INET;
addr_rem.sin_port = htons(remotePort);
addr_rem.sin_addr.s_addr = htonl(remoteAddr);
sendto(handle, packetData, packetLength, 0, (struct sockaddr *)&addr_rem, sizeof(addr_rem));
爲TCP沒有問題,但對於UDP,我想讓服務器知道我的IP地址,以便他在同一地址回覆我。 但我運行時,所有的客戶端和服務器獲得相同的IP地址。我可以採用某種改變 –
你客戶端的地址在'recvfrom' – mark
,但如果我有一臺電腦,服務器和客戶端都具有相同的IP地址。所以我怎麼能區分2 –
,你將有服務器監聽本地主機,127.0.0.1,然後每個客戶端將連接到本地主機(127.0.0.1),該服務器監聽端口上。在這裏,我將展示它的外觀。
服務器的代碼可能是這樣的:
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netdb.h>
int main() {
struct addrinfo hints, *res;
int sockfd;
int byte_count;
socklen_t fromlen;
struct sockaddr_storage addr;
char buf[512];
char ipstr[INET6_ADDRSTRLEN];
// get host info, make socket, bind it to port 9999
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC; // use IPv4 or IPv6, whichever
hints.ai_socktype = SOCK_DGRAM;
hints.ai_flags = AI_PASSIVE;
getaddrinfo(NULL, "9999", &hints, &res);
sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
bind(sockfd, res->ai_addr, res->ai_addrlen);
// no need to accept(), just recvfrom():
fromlen = sizeof addr;
byte_count = recvfrom(sockfd, buf, sizeof buf, 0, (sockaddr*)&addr, &fromlen);
printf("recv()'d %d bytes of data in buf\n", byte_count);
printf("from IP address %s\n",
inet_ntop(addr.ss_family,
(const void*)(&((struct sockaddr_in *) &addr)->sin_addr), ipstr, sizeof ipstr));
return 0;
}
你可以嘗試在該服務器通過NC與-vu選項監聽終端:
[email protected]:~# nc -vu localhost 9999
,應該從這樣的服務器獲得的輸出:
recv()'d 29 bytes of data in buf
from IP address 127.0.0.1
客戶端代碼:
#define DEST_PORT 9999
#define DEST_IP "127.0.0.1"
int main(int argc, char** argv) {
char *secret_message = "The Cheese is in The Toaster";
int dgram_socket;
struct sockaddr_in dest_addr;
// now with UDP datagram sockets:
// datagram sockets and recvfrom()
dest_addr.sin_family = AF_INET;
/* short, network byte order */
dest_addr.sin_port = htons(DEST_PORT);
dest_addr.sin_addr.s_addr = inet_addr(DEST_IP);
/* zero the rest of the struct */
memset(&(dest_addr.sin_zero), 0, 8);
dgram_socket = socket(dest_addr.sin_family, SOCK_DGRAM, 0);
// send secret message normally:
sendto(dgram_socket, secret_message, strlen(secret_message) + 1, 0,
(struct sockaddr*) &dest_addr, sizeof dest_addr);
return 0;
}
再次,發射時你應該從服務器的輸出與此類似:
recv()'d 29 bytes of data in buf
from IP address 127.0.0.1
How client IP address and port knows to the server ?,
Ans: When datagram is recieved(readyRead signal is emited), you can use readDatagram API
socketServer.readDatagram(buffer.data(),buffer.size(),&sender,&port);
sender = IPaddress of client
por = portNumber of client.
這裏是同一本地主機上使用Qt的QUdpSocket提供,1 UDP Sever的解決方案,用多個客戶端,測試它正在工作。註釋的代碼,在必要
有兩個控制檯應用程序(UDPServer和UDPClient)
How to test
1. Run UDPServer, it will listen on port 9999
2. Run UDPClient(First instance)
3. Run UDPClient(second instance)
Result:
Please check below screenshot
UDPServer代碼
>的main.cpp
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
UDPServer server;
return a.exec();
}
> UDPServer。ħ
#ifndef UDPSERVER_H
#define UDPSERVER_H
#include <QObject>
#include <QUdpSocket>
class UDPServer : public QObject
{
Q_OBJECT
public:
explicit UDPServer(QObject *parent = 0);
void WriteData(const QString&);
public slots:
void readReady();
private:
QUdpSocket socketServer;
};
#endif // UDPSERVER_H
> UDPServer.cpp
#include "UDPServer.h"
UDPServer::UDPServer(QObject *parent) :QObject(parent),socketServer(this)
{
qDebug()<<"I am UDP server, listening on 9999";
// Listen to 9999 port server
socketServer.bind(QHostAddress::LocalHost,9999);
connect(&socketServer,SIGNAL(readyRead()),this,SLOT(readReady()));
}
void UDPServer::readReady()
{
QByteArray buffer;
buffer.resize(socketServer.pendingDatagramSize());
QHostAddress sender;
quint16 port;
socketServer.readDatagram(buffer.data(),buffer.size(),&sender,&port);
qDebug()<<"Datagram Recieved From";
qDebug()<<"Client IP" << sender.toString();
qDebug()<<"Client Port Number " << port;
qDebug()<<"\n\n";
// Write to the client,need to specify the client port number.
QByteArray clientData;
clientData.append("data");
socketServer.writeDatagram(clientData, QHostAddress::LocalHost, port);
}
UDPClient代碼
>的main.cpp
#include <QtCore/QCoreApplication>
#include "udpclient.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
UDPClient client;
client.WriteData("What is my IP");
return a.exec();
}
> udpclient.h
#ifndef UDPCLIENT_H
#define UDPCLIENT_H
#include <QObject>
#include <QUdpSocket>
class UDPClient : public QObject
{
Q_OBJECT
public:
explicit UDPClient(QObject *parent = 0);
void WriteData(const QString&);
public slots:
void readReady();
private:
QUdpSocket clientSocket;
};
#endif // UDPCLIENT_H
> udpclient.cpp
#include "udpclient.h"
UDPClient::UDPClient(QObject *parent) :QObject(parent), clientSocket(this)
{
qDebug()<<"I am your client";
connect(&clientSocket,SIGNAL(readyRead()),this,SLOT(readReady()));
}
void UDPClient::WriteData(const QString& data)
{
QByteArray clientData;
clientData.append(data);
// write to the port, listening by the server.
qDebug()<<"Writing datagram to 9999 port";
clientSocket.writeDatagram(clientData, QHostAddress::LocalHost, 9999);
}
void UDPClient::readReady()
{
// got response from server, so clientSoclet port number can get.
qDebug()<< "Reacieved response from server through my port(Client port No):" << clientSocket.localPort();
QByteArray buffer;
buffer.resize(clientSocket.pendingDatagramSize());
QHostAddress sender;
quint16 port;
clientSocket.readDatagram(buffer.data(),buffer.size(),&sender,&port);
// To read server IP
qDebug()<< "Server IP Responded" << sender.toString();
qDebug()<< "Server Port Number" << port;
}
(IP地址)分配給每個設備的數字標籤.. – Ashif
所以如何做我想做什麼?我想要一臺PC上的許多客戶端和服務器。我應該給他們每個人不同的端口號碼嗎? ,但我想他們每個人給一個不同的IP地址。那可能嗎 ? –
客戶端從不偵聽IP,客戶端連接到服務器,對於該客戶端主要需要服務器的IP和偵聽端口。 – Ashif