有時候會遇到QT界面程序經過網路與普通的linux應用程序進行數據傳送的情況:(UDP協議,非TCP協議)
個人感覺比管道、共享內存、信號量、消息隊列好用
Qt udp_client
1.我們新建Qt4 GuiApplication,工程名為“udpSender”,選中QtNetwork模塊,Base class選擇QWidget。
2.我們在widget.ui文件中,往界面上添加一個Push Button,進入其單擊事件槽函數。
3.我們在widget.h文件中更改。
添加頭文件:#include <QtNetwork>
添加private私有對象:QUdpSocket *sender;
4.我們在widget.cpp中進行更改。
在構造函數中添加:sender = new QUdpSocket(this);
void Widget::on_pushButton_clicked() {
QByteArray datagram = “hello world!”;
sender->writeDatagram(datagram.data(),datagram.size(),
QHostAddress("192.168.1.10"),8888); //ip為目標機ip
}
這裡我們定義了一個QByteArray類型的數據報datagram,其內容為“hello world!”。然後我們使用QUdpSocket類的writeDatagram()函數來發送數據報,這個函數有四個參數,分別是數據報的內容,數據報的大小,主機地址和端口號。對於數據報的大小,它根據平台的不同而不同,但是這裡建議不要超過512字節。對於端口號,它是可以隨意指定的,但是一般1024以下的端口號通常屬於保留端口號,所以我們最好使用大於1024的端口,最大為65535。我們這裡使用了8888這個端口號,一定要注意,在下面要講的服務器程序中,也要使用相同的端口號。
應用程序:udp_server.c
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <netdb.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <arpa/inet.h>
#define SERVER_PORT 8888
#define MAX_MSG_SIZE 1024
void udps_respon(int sockfd)
{
struct sockaddr_in addr;
int addrlen,n;
char msg[MAX_MSG_SIZE];
while(1)
{ /* 從網絡上讀,並寫到網絡上 */
bzero(msg,sizeof(msg)); // 初始化,清零
addrlen = sizeof(struct sockaddr);
n=recvfrom(sockfd,msg,MAX_MSG_SIZE,0,(struct sockaddr*)&addr,&addrlen); // 從客戶端接收消息
msg[n]=0;//將收到的字符串尾端添加上字符串結束標志
/* 顯示服務端已經收到了信息 */
fprintf(stdout,"Server have received %s",msg); // 顯示消息
}
}
int main(void)
{
int sockfd;
struct sockaddr_in addr;
/* 服務器端開始建立socket描述符 */
sockfd=socket(AF_INET,SOCK_DGRAM,0);
if(sockfd<0)
{
fprintf(stderr,"Socket Error:%s\n",strerror(errno));
exit(1);
}
/* 服務器端填充 sockaddr結構 */
bzero(&addr,sizeof(struct sockaddr_in));
addr.sin_family=AF_INET;
addr.sin_addr.s_addr=htonl(INADDR_ANY);
addr.sin_port=htons(SERVER_PORT);
/* 捆綁sockfd描述符 */
if(bind(sockfd,(struct sockaddr *)&addr,sizeof(struct sockaddr_in))<0)
{
fprintf(stderr,"Bind Error:%s\n",strerror(errno));
exit(1);
}
udps_respon(sockfd); // 進行讀寫操作
close(sockfd);
}