TCP/socket 编程笔记

2 篇文章 0 订阅

 

一、基于Qt的TCP通讯

  • 服务器和客户端的框图

1. Qt 工程包含以下

QT += network

CONFIG += C++11
  • Service端

1. 服务器(Server)包含2个头文件

#include <QTcpServer>
#include <QTcpSocket>

2. 在class Tcp_Server 的 private 内创建2个指针:

QTcpServer *tcpServer;
QTcpSocket *tcpSocket;

3. 构造函数处理:

Tcp_Server::Tcp_Server(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::Tcp_Server)
{
    ui->setupUi(this);
    this->setWindowTitle("TCP Server   ming.liu@2020-06-21");
    tcpSocket = NULL;
    tcpServer = NULL;
    ui->textEdit_read->setReadOnly(true);

    tcpServer = new QTcpServer(this);
    tcpServer->listen(QHostAddress::Any, 8888); //Any默认绑定网口的所有ip地址

    /* 绑定ip和端口号 */
    connect(tcpServer, &QTcpServer::newConnection,
            [=]()
            {
                //取出建立好连接的套接字
                tcpSocket = tcpServer->nextPendingConnection();

                //获取客户端的ip和端口
                QString ip = tcpSocket->peerAddress().toString();
                uint16_t port = tcpSocket->peerPort();
                QString temp = QString("[%1:%2]:成功连接").arg(ip).arg(port);
                ui->textEdit_read->setText(temp);

                //接收客户端发来的数据,并显示
                connect(tcpSocket,&QTcpSocket::readyRead,
                        [=]()
                        {
                            QByteArray array = tcpSocket->readAll();
                            ui->textEdit_read->append(array);
                        }
                );
            }
    );


}

4. 服务器(Server)端发送

void Tcp_Server::on_BT_send_clicked()
{
    if(tcpSocket == NULL)
    {
        return;
    }

    //获取编辑区内容
    QString str = ui->textEdit_write->toPlainText();
    tcpSocket->write(str.toUtf8().data()); //server发送
}

5. 服务器(Server)断开连接

void Tcp_Server::on_BT_disconnect_clicked()
{
    //主动和对方断开连接
    tcpSocket->disconnectFromHost();
    tcpSocket->close(); //加上此句,在Debug区可以看到打印信息
    ui->textEdit_read->setText("已断开");
}

 

  • Client 端

1. 包含头文件(注意:服务器是包含2个头文件)

#include <QTcpSocket>

2. 在 class tcpClient 的private下创建 QTcpSocket 的对象指针

QTcpSocket *tcpSocket;

如下图所示:

3. 构造函数处理 (重点)

tcpClient::tcpClient(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::tcpClient)
{
    ui->setupUi(this);
    this->setWindowTitle("TCP Client");

    tcpSocket = NULL;

    //分配空间,指定父对象
    tcpSocket = new QTcpSocket(this);          // 1--实例化tcpSocket 的对象
    connect(tcpSocket, &QTcpSocket::connected, // 2--已连接的信号槽
            [=]()
            {
                ui->textEdit_read->setText("已连接");
            }
    );

    connect(tcpSocket,&QTcpSocket::readyRead,  // 3-- 接收数据处理
            [=]()
            {
                //获取对方发送的内容
                QByteArray array = tcpSocket->readAll();

                //显示到编辑区
                ui->textEdit_read->append(array);
            }
    );
}

4. connect 服务器

void tcpClient::on_BT_connect_clicked()
{
    //获取服务器ip和端口
    QString ip = ui->lineEdit_ip->text();
    qint16 port = ui->lineEdit_port->text().toInt();

    //主动和服务器建立连接
    tcpSocket->connectToHost(QHostAddress(ip),port);
}

5. 向服务器发送数据

void tcpClient::on_BT_send_clicked()
{
    //获取待发送内容
    QString str = ui->textEdit_write->toPlainText();
    tcpSocket->write(str.toUtf8().data());

}

6. 与服务器断开连接

void tcpClient::on_BT_disconnect_clicked()
{
    //主动和对方断开连接
    tcpSocket->disconnectFromHost();
    tcpSocket->close(); //加上此句,在Debug区可以看到打印信息
     ui->textEdit_read->setText("已断开");
}

 

所实现的Demo

 

资源代码:https://gitee.com/the_wind_is_clear/QtSerialDemo/blob/QT_socket/README.md

 

 

二、基于Linux的socket通讯

下面展示的是韦东山的进程间使用socket的示例Demo

 

2.1 服务器(server)端

/**********************************************************************

 * 功能描述: 1.server打印client发送过来的字符串,并将该字符串回发给client

 * 输入参数: 无

 * 输出参数: 无

 * 返 回 值: 无

 ***********************************************************************/

server.c

/**********************************************************************
 * 功能描述: 1.server打印client发送过来的字符串,并将该字符串回发给client
 * 输入参数: 无
 * 输出参数: 无
 * 返 回 值: 无
 * 修改日期        版本号     修改人          修改内容
 * -----------------------------------------------
 * 2020/05/16       V1.0      zh(ryan)        创建
 ***********************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/un.h>

int main(int argc, char *argv[])
{
    int lfd ,ret, cfd;
    struct sockaddr_un serv, client;
    socklen_t len = sizeof(client);
    char buf[1024] = {0};
    int recvlen;

    //创建socket
    lfd = socket(AF_LOCAL, SOCK_STREAM, 0);
    if (lfd == -1) {
        perror("socket error");
        return -1;
    }

    //如果套接字文件存在,删除套接字文件
    unlink("server.sock");

    //初始化server信息
    serv.sun_family = AF_LOCAL;
    strcpy(serv.sun_path, "server.sock");

    //绑定
    ret = bind(lfd, (struct sockaddr *)&serv, sizeof(serv));
    if (ret == -1) {
        perror("bind error");
        return -1;
    }

    //设置监听,设置能够同时和服务端连接的客户端数量
    ret = listen(lfd, 36);
    if (ret == -1) {
        perror("listen error");
        return -1;
    }

    //等待客户端连接
    cfd = accept(lfd, (struct sockaddr *)&client, &len);
    if (cfd == -1) {
        perror("accept error");
        return -1;
    }
    printf("=====client bind file:%s\n", client.sun_path);
    
    while (1) {
        recvlen = recv(cfd, buf, sizeof(buf), 0);
        if (recvlen == -1) {
            perror("recv error");
            return -1;
        } else if (recvlen == 0) {
            printf("client disconnet...\n");
            close(cfd);
            break;
        } else {
            printf("server recv buf: %s\n", buf);
            send(cfd, buf, recvlen, 0);
        }
    }
    
    close(cfd);
    close(lfd);
    return 0;
}

 

2.2 客户端(Client)

/**********************************************************************

 * 功能描述: 1.client从标准输入获取到一个字符串,然后将这个字符串发送给server

 * 输入参数: 无

 * 输出参数: 无

 * 返 回 值: 无

 ***********************************************************************/

/**********************************************************************
 * 功能描述: 1.client从标准输入获取到一个字符串,然后将这个字符串发送给server
 * 输入参数: 无
 * 输出参数: 无
 * 返 回 值: 无
 * 修改日期        版本号     修改人          修改内容
 * -----------------------------------------------
 * 2020/05/16       V1.0      zh(ryan)        创建
 ***********************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/un.h>

int main(int argc, char *argv[])
{
    int lfd ,ret;
    struct sockaddr_un serv, client;
    socklen_t len = sizeof(client);
    char buf[1024] = {0};
    int recvlen;

    //创建socket
    lfd = socket(AF_LOCAL, SOCK_STREAM, 0);
    if (lfd == -1) {
        perror("socket error");
        return -1;
    }

    //如果套接字文件存在,删除套接字文件
    unlink("client.sock");

    //给客户端绑定一个套接字文件
    client.sun_family = AF_LOCAL;
    strcpy(client.sun_path, "client.sock");
    ret = bind(lfd, (struct sockaddr *)&client, sizeof(client));
    if (ret == -1) {
        perror("bind error");
        return -1;
    }

    //初始化server信息
    serv.sun_family = AF_LOCAL;
    strcpy(serv.sun_path, "server.sock");
    //连接
    connect(lfd, (struct sockaddr *)&serv, sizeof(serv));

    while (1) {
        fgets(buf, sizeof(buf), stdin);
        send(lfd, buf, strlen(buf)+1, 0);

        recv(lfd, buf, sizeof(buf), 0);
        printf("client recv buf: %s\n", buf);
    }

    close(lfd);
    return 0;
}

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值