创建基于TCP的C/S应用程序

QTcpServer和QTcpSocket类是专门用于实现TCP下的客户端和服务器程序的类。

QTcpSocket是从QIODevice类继承下来的,使用QDataStream或者QTextStream类可以读写它,值得注意的是:从网络中读取数据与从文件中读取数据的不同在于使用>>操作符之前我们必须确保我们已经接收到了足够的数据,否则会成为未定义的动作。

 

实例的创建与分析

创建目标:使用一个自定义的基于块传输的C/S应用程序。

客户端取名Trip Planner,允许用户计划他们的下一个火车站,服务器取名Trip Server,用于给客户端提供火车票信息。先从客户端程序开始,录入信息包括:起点,终点,日期,时间,两个选择按钮分别用来选择出发与到达的时间。点击search按钮后,应用程序给服务器发送请求,服务器返回一系列满足客户端要求的火车时刻表,客户端将时刻表显示在QTableWidget上,下面的QLabel标签对象用于显示状态,接下来就是完成功能实现的代码

 

【槽函数分析】

当点击search按钮时触发槽函数connectToServer与服务器建立连接,调用connectToHost函数实现连接,当连接成功时QTcpSocket对象会发出connected信号,否则会发出error信号,所以,根据socket对象发出的信号来编写各自对应的槽函数sendRequest()和error()

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
本文将介绍如何使用MFC Winsock实现基于TCP协议的C/S聊天程序。 1. 创建MFC应用程序 首先,我们需要创建一个MFC应用程序。在创建向导中选择“单文档应用程序”类型,勾选“包含MFC的ActiveX控件”和“支持ActiveX控件”,其他选项默认即可。 2. 添加界面元素 在资源视图中添加两个编辑框和一个按钮,用于输入和显示聊天内容,以及发送消息。 3. 编写代码 在Dlg.cpp文件中添加以下代码: 在头文件中添加以下头文件: #include "stdafx.h" #include "Dlg.h" #include "afxdialogex.h" #include <winsock2.h> #pragma comment(lib, "ws2_32.lib") 在OnInitDialog()函数中添加以下代码: WSADATA wsaData; SOCKET ConnectSocket = INVALID_SOCKET; struct addrinfo *result = NULL, *ptr = NULL, hints; int iResult; // Initialize Winsock iResult = WSAStartup(MAKEWORD(2,2), &wsaData); if (iResult != 0) { MessageBox(_T("WSAStartup failed with error: %d"), iResult); return FALSE; } ZeroMemory(&hints, sizeof(hints)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; // Resolve the server address and port iResult = getaddrinfo(_T("localhost"), _T("27015"), &hints, &result); if ( iResult != 0 ) { MessageBox(_T("getaddrinfo failed with error: %d"), iResult); WSACleanup(); return FALSE; } // Attempt to connect to an address until one succeeds for(ptr=result; ptr != NULL ;ptr=ptr->ai_next) { // Create a SOCKET for connecting to server ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol); if (ConnectSocket == INVALID_SOCKET) { MessageBox(_T("socket failed with error: %ld\n"), WSAGetLastError()); WSACleanup(); return FALSE; } // Connect to server. iResult = connect( ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen); if (iResult == SOCKET_ERROR) { closesocket(ConnectSocket); ConnectSocket = INVALID_SOCKET; continue; } break; } freeaddrinfo(result); if (ConnectSocket == INVALID_SOCKET) { MessageBox(_T("Unable to connect to server!")); WSACleanup(); return FALSE; } // Set the mode of the socket to be nonblocking u_long iMode = 1; iResult = ioctlsocket(ConnectSocket, FIONBIO, &iMode); if (iResult == SOCKET_ERROR) { MessageBox(_T("ioctlsocket failed with error: %d"), WSAGetLastError()); closesocket(ConnectSocket); WSACleanup(); return FALSE; } // Disable Nagle's algorithm char value = 1; setsockopt(ConnectSocket, IPPROTO_TCP, TCP_NODELAY, &value, sizeof(value)); 在OnDestroy()函数中添加以下代码: // shutdown the connection since no more data will be sent iResult = shutdown(ConnectSocket, SD_SEND); if (iResult == SOCKET_ERROR) { MessageBox(_T("shutdown failed with error: %d"), WSAGetLastError()); closesocket(ConnectSocket); WSACleanup(); return FALSE; } // cleanup closesocket(ConnectSocket); WSACleanup(); 在OnBnClickedButtonSend()函数中添加以下代码: // Send a message CString strMsg; m_edtMsg.GetWindowText(strMsg); char buf[1024]; strcpy_s(buf, CT2A(strMsg.GetBuffer())); iResult = send(ConnectSocket, buf, strlen(buf), 0); if (iResult == SOCKET_ERROR) { MessageBox(_T("send failed with error: %d"), WSAGetLastError()); closesocket(ConnectSocket); WSACleanup(); return FALSE; } m_lstMsg.AddString(strMsg); m_edtMsg.SetWindowText(_T("")); 在OnReceive()函数中添加以下代码: char buf[1024]; int iResult = recv(ConnectSocket, buf, sizeof(buf), 0); if (iResult > 0) { CString strMsg(buf); m_lstMsg.AddString(strMsg); } else if (iResult == 0) { MessageBox(_T("Connection closed")); closesocket(ConnectSocket); WSACleanup(); return FALSE; } else { int err = WSAGetLastError(); if (err != WSAEWOULDBLOCK) { MessageBox(_T("recv failed with error: %d"), err); closesocket(ConnectSocket); WSACleanup(); return FALSE; } } 4. 编译运行 现在我们可以编译运行程序,在输入框中输入消息并点击发送按钮,就可以发送消息到服务器并在列表框中显示。当接收到服务器返回的消息时,也会在列表框中显示。 注意:本程序仅实现了客户端的代码,需要和服务器端代码配合使用才能实现完整的C/S聊天程序。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值