QT5之UDP 通訊
阿新 • • 發佈:2020-07-26
UDP 通訊
UDP通訊的優點
UDP無連線通訊
- 可以探測附近的裝置
- 減輕服務端的壓力
UDP步驟
服務端
- 定義一個套接字s
- 定義檔案描述符
- 定義緩衝字串
- 申請一個套接字作用在檔案描述符上
- 引數一:協議 -> IPv4/IPv6 PF_INET/PF_INET6
- 引數二:套接字型別 -> UDP無連線/TCP有連線 SOCK_DGRAM/SOCK_STREAM
- 引數三:申請套接字
- 重新整理套接字s 為zero
- 賦值:
s.sin_family = AF_INET; //IPV4協議族 s.sin_port = htons(8888); //埠號 s.sin_addr.s_addr = INADDR_ANY; //預設地址0x00000000
-
繫結埠
- 引數一:輸入檔案描述符
- 引數二:套接字的地址&s
- 引數三:s的大小
這個套接字有了本地IP,埠,通訊協議
-
接收客戶端發來的資訊
- 引數一:套接字
- 引數二:緩衝字串
- 引數三:緩衝字串的大小
- 引數四:標誌位設定為0
- 引數五:套接字s的地址
- 引數六:套接字s的長度的二地址
客戶端
1 ~ 6 的步驟與服務端相同
- 對字串幅值
- 傳送資料
參考:UDP簡單實戰
原始碼
//服務端:接收 int main() { struct sockaddr_in s; //定義套接字 int sock; //定義檔案表述符 char buff[182]; //緩衝陣列 if((sock = socket(AF_INET, SOCK_DGRAM, 0))==-1) perror("error"); memset(&s,0,sizeof(s)); //重新整理 s.sin_family = AF_INEF; s.sin_port = htons(8888); s.sin_addr.s_addr = INADDR_ANY; if( bind(sock, (struct sockaddr *)&s, sizeof(s)) == -1 ) perror("error"); int sock_len = sizeof(s); recvfrom( sock, buff, sizeof(buff)-1, 0, (struct sockaddr *)&s, &sock_len); printf("message:%s", buff); return 0; }
//客戶端:傳送 int main() { struct sockaddr_in s; //定義套接字 int sock; //定義檔案表述符 char buff[182]; //緩衝陣列 if((sock = socket(AF_INET, SOCK_DGRAM, 0))==-1) perror("error"); memset(&s,0,sizeof(s)); //重新整理 s.sin_family = AF_INEF; s.sin_port = htons(8888); s.sin_addr.s_addr = INADDR_ANY; scanf("%s", buff); //對字串進行賦值 sendto(sock, buff, strlen(buff), 0, (struct sockaddr *)&s, sizeof(s)); return 0; }
總結
UDP通訊需要的因素:
- 雙方的埠號
- 對方的IP (自己的IP手動設定)
QT實戰
pro檔案
加入network環境:在core gui後面加入 network
QT += core gui network
mainwindow.cpp
udpsocket=new QUdpSocket(this); //新建一個套接字socket
/* 繫結本機埠號,允許其他伺服器繫結同樣的IP和埠,即使改地址被另外一個套接字繫結也應該重新繫結 */
udpsocket->bind((quint16)51303, QUdpSocket::ShareAddress | QUdpSocket::ReuseAddressHint);
connect(udpsocket,SIGNAL(readyRead()),this,SLOT(recvMsg())); // 發起連線
/* 關閉UDP */
udpsocket -> close();
/* 接收資訊 */
void MainWindow::recvMsg(){
if(udpsocket->hasPendingDatagrams()){
QByteArray datagram;
datagram.resize(udpsocket->pendingDatagramSize());
udpsocket->readDatagram(datagram.data(),datagram.size());
ui->listWidget->insertItem(0,datagram);
}
}
QHostAddress addr("192.168.1.100"); //目標地址
QByteArray msg;
msg.append(ui->lineEdit->text()); //傳送資訊內容
udpsocket->writeDatagram(msg,addr,(quint16)51303); //傳送目標機的地址和埠號
mainwindow.h
加入UDP標頭檔案
#include <QUdpSocket>
公共成員宣告
public:
QUdpSocket *udpsocket;
增加宣告一個private slots
private slots:
void recvMsg();
參考:寫個小小的UDP客戶端