SOCKET socket( int af, int type, int protocol ); 应用程序调用socket函数来创建一个能够进行网络通信的套接字。第一个参数指定应用程序使用的通信协议的协议族,对于TCP/IP协议族,该参数置AF_INET; 第二个参数指定要创建的套接字类型,流套接字类型为SOCK_STREAM、数据报套接字类型为SOCK_DGRAM、原始套接字SOCK_RAW(WinSock接口并不适用某种特定的协议去封装它,而是由程序自行处理数据报以及协议首部);第三个参数指定应用程序所使用的通信协议。
在LINUX下进行网络编程,我们可以使用LINUX提供的统一的套接字接口。但是这种方法牵涉到太多的结构体,比如IP地址,端口转换等,不熟练的人往往容易犯这样那样的错误。QT中提供的SOCKET完全使用了类的封装机制,使用户不需要接触底层的各种结构体操作。而且它采用QT本身的signal-slot机制,使编写的程序更容易理解。
QT中共提供四个与套按字相关的类,分别是:
- QServerSocket:TCP-based server
- QSocket: Buffered TCP connection
- QSocketDevice: Platform-independent low-level socket API
- QSocketNotifier: Support for socket callbacks
下面介绍使用QT进行网络编程,我们使用一个简单的C/S模式网络程序说明如何使用QT中的套接字。同时我们用TCP和UDP两种协议实现这个程序(该程序客户端与服务端各向对方发送一个字符口串“abc”)
1、UDP实现
UDP是不连接协议,没有客户端与服务端的概念。
(1)建立套接字相关对象
- QSocketDevice *MUReceiveSocket; //套接字对象
- QSocketNotifier *MSocketNotifier; //套接字监听对象
(2)初始化套接字相关对象
- MUReceiveSocket=new QSocketDevice(QSocketDevice::Datagram);
- //UDP初始化
- QHostAddress MyAddress;
- QString FakeAddress;
- FakeAddress = get_eth1_ip(); //取得接口IP
- MyAddress.setAddress(FakeAddress);
- MUReceiveSocket->bind(MyAddress,Port);
- //绑定到指定网络接口地址(IP),指定逻辑端口
- MSocketNotifier = new QSocketNotifier(MUReceiveSocket->socket(),QSocketNotifier::Read,0,"MSocketNotifier");
- //监听MUReceiveSocket套接字
(3)定义用实现响应slot
- virtual void OnMReceive();
- void Client::OnMReceive(){
- int ByteCount,ReadCount;
- char *IncommingChar;
- fprintf(stderr,"Load a piece of Message!\n");
- ByteCount=MUReceiveSocket->bytesAvailable();
- IncommingChar=(char *)malloc(ByteCount+1);
- ReadCount=MUReceiveSocket->readBlock(IncommingChar,ByteCount);
- IncommingChar[ByteCount]='\0';
- fprintf(stderr,“%s“,IncommingChar); //打印接收的字符串
- }
(4)关联套接字的signal和接收slot
- connect(MSocketNotifier,SIGNAL(activated(int)),this,SLOT(OnMReceive()));
- //当MSocketNotifier检测到MUReceiveSocket活跃时调用OnMReceive
(5)发送字符串
- char information[20];
- strcpy(information,“abc“);
- MUReceiveSocket->writeBlock(information,length,MyAddress,2201);
2、TCP实现
TCP的实现与UDP的实现大同小异,它是面象连接的协议。这里只介绍与UDP不同的地方。
服务端:
(1)套接字对象的定义
比UDP多定义一个套接字,一个用来监听端口,一个用来通信。
建立一个QSSocket类继承QServerSocket
- QSSocket *ServerSocket; //TCP-based server
- QSocketDevice *ClientSocket;
- QSocketNotifier *ClientNotifier;
- QSocketNotifier *ServerNotifier;
(2)套接字的初始化
- QHostAddress MyAddress;
- QString FakeAddress;
- FakeAddress = "127.0.0.1";
- MyAddress.setAddress(FakeAddress);
- UINT Port=1234;
- ServerSocket=new QSSocket(MyAddress,Port,this,0); //指定监听地址及端口
- //这里也可以使用QServerSocket类
- ClientSocket=new QSocketDevice(QSocketDevice::Stream);
- ClienttNotifier = new QSocketNotifier(ClientSocket->socket(),QSocketNotifier::Read,0,"ClientSocket");
(3)响应连接
只需要在QSSocket的构造函数里添加如下代码:
- ServerSocket->newConncetion(ClientSocket->socket());
当收到客户端的连接后,ClientSocket自动响应,并接收数据。
(4)接收信息slot与UDP一致,这里不在叙述。
客户端实现:
客户端的实现与UDP实现大同小异,不同的地方只是客户端套接字不需要bind端口,因为连接上服务端后TCP会保持这个连接,直到通信的结束。
小结:对于本篇文章实现Qt 中Socket编程,讲解到这,客户端和服务端的实现很important!实现套接字的网络通信。希望本文对你有帮助!!!
【编辑推荐】