提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
Socket通信
前言
提示:这里可以添加本文要记录的大概内容:
例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。
提示:以下是本篇文章正文内容,下面案例可供参考
一、TCP通信
1. 简单的winTcpSocket实现
1.1 TcpClient代码实现
// ConsoleApplication21.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#include <windows.h>
#pragma comment(lib,"ws2_32.lib")
//添加此句,屏蔽"warning作为error", 提高兼容性
#pragma warning(disable:4996)
int main(int argc, char *argv[])
{
WORD sockVersion = MAKEWORD(2, 2);
WSADATA data;
if (WSAStartup(sockVersion, &data) != 0)
{
return 0;
}
SOCKET sclient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sclient == INVALID_SOCKET)
{
printf("invalid socket !");
return 0;
}
sockaddr_in serAddr;
serAddr.sin_family = AF_INET;
serAddr.sin_port = htons(8888);
serAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
if (connect(sclient, (sockaddr *)&serAddr, sizeof(serAddr)) == SOCKET_ERROR)
{
printf("connect error !");
closesocket(sclient);
return 0;
}
char *sendData = "[TCP][Clietn]Hello TCP Server,i am TCP Client!\n";
send(sclient, sendData, strlen(sendData), 0);
char recData[255];
int ret = recv(sclient, recData, 255, 0);
if (ret > 0)
{
recData[ret] = 0x00;
printf(recData);
}
closesocket(sclient);
WSACleanup();
return 0;
}
1.2 TcpServer代码实现
// ConsoleApplication22.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "stdafx.h"
#include <winsock2.h>
#include <windows.h>
#include <Ws2tcpip.h>
#pragma comment(lib,"ws2_32.lib")
int main(int argc, char* argv[])
{
//初始化WSA
WORD sockVersion = MAKEWORD(2, 2);
WSADATA wsaData;
if (WSAStartup(sockVersion, &wsaData) != 0)
{
return 0;
}
//创建套接字
SOCKET slisten = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (slisten == INVALID_SOCKET)
{
printf("socket error !");
return 0;
}
//绑定IP和端口
sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(8888);
sin.sin_addr.S_un.S_addr = INADDR_ANY;
if (bind(slisten, (LPSOCKADDR)&sin, sizeof(sin)) == SOCKET_ERROR)
{
printf("bind error !");
}
//开始监听
if (listen(slisten, 5) == SOCKET_ERROR)
{
printf("listen error !");
return 0;
}
//循环接收数据
SOCKET sClient;
sockaddr_in remoteAddr;
int nAddrlen = sizeof(remoteAddr);
char revData[255];
while (true)
{
printf("[TCP][Server] Listening waiting...\n");
sClient = accept(slisten, (SOCKADDR *)&remoteAddr, &nAddrlen);
if (sClient == INVALID_SOCKET)
{
printf("accept error !");
continue;
}
printf("[TCP][Server]a client wasaccepted\r\n"); // inet_ntoa(remoteAddr.sin_addr)函数:将网络地址转换成“.”点隔的字符串格式
//接收数据
int ret = recv(sClient, revData, 255, 0);
if (ret > 0)
{
revData[ret] = 0x00;
printf(revData);
}
//发送数据
char * sendData = "[TCP][Server] hello TCP Client,i am TCP Server !\n";
send(sClient, sendData, strlen(sendData), 0);
closesocket(sClient);
}
closesocket(slisten);
WSACleanup();
return 0;
}
1.3 代码执行结果分析
- 先启动服务端,服务端进入监听状态:
- 启动客户端后,TCP的服务端接收了来自客户端的链接请求后,也收到了来自客户端的数据:
- 客户端收到了来自服务端的数据
2. TcpSocketClient定时发送心跳
#include <iostream>
#include <string>
#include <thread>
#include <chrono>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
class TCPClient {
public:
TCPClient(const std::string& serverIP, int port) : m_serverIP(serverIP), m_port(port) {}
void start() {
// 创建Socket并连接服务器
if ((m_sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("Failed to create socket");
return;
}
struct sockaddr_in servAddr{};
servAddr.sin_family = AF_INET;
servAddr.sin_port = htons(m_port);
if (inet_pton(AF_INET, m_serverIP.c_str(), &servAddr.sin_addr) <= 0) {
perror("Invalid address or address not supported");
close(m_sockfd);
return;
}
if (connect(m_sockfd, reinterpret_cast<struct sockaddr*>(&servAddr), sizeof(servAddr)) < 0) {
perror("Connection failed");
close(m_sockfd);
return;
}
// 开始定时发送心跳包线程
m_heartbeatThread = std::thread([this](){ heartbeat(); });
}
private:
void heartbeat() {
while (true) {
// 构造心跳数据包(这里只是一个示例)
const char* data = "Heartbeat";
// 向服务器发送心跳包
send(m_sockfd, data, strlen(data), 0);
// 休眠指定时间后再次发送心跳包
std::this_thread::sleep_for(std::chrono::seconds(5));
}
}
std::string m_serverIP; // 服务器IP地址
int m_port; // 服务器端口号
int m_sockfd; // Socket文件描述符
std::thread m_heartbeatThread; // 定时发送心跳包的线程
};
int main() {
std::string serverIP = "127.0.0.1"; // 设置服务器IP地址
int port = 8080; // 设置服务器端口号
TCPClient client(serverIP, port);
client.start();
// 等待主线程结束或按Ctrl+C退出
for (;;) {
sleep(1);
}
}
// --------------------------------TCP客户端类:定时5秒发一次向服务端发送一次心跳
#include <iostream>
#include <string>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <thread>
#include <chrono>
class TCPClient {
public:
TCPClient(const std::string& serverIP, int port) : m_serverIP(serverIP), m_port(port) {}
void start() {
// 创建Socket
if ((m_sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("Failed to create socket");
return;
}
// 设置服务器地址信息
struct sockaddr_in servAddr{};
servAddr.sin_family = AF_INET;
servAddr.sin_port = htons(m_port);
inet_pton(AF_INET, m_serverIP.c_str(), &servAddr.sin_addr);
// 连接到服务器
if (connect(m_sockfd, reinterpret_cast<struct sockaddr*>(&servAddr), sizeof(servAddr)) == -1) {
perror("Failed to connect to the server");
close(m_sockfd);
return;
}
// 开始发送心跳消息
sendHeartbeat();
}
private:
void sendHeartbeat() {
while (true) {
// 构造心跳消息
const char heartbeat[] = "heartbeat";
// 发送心跳消息
ssize_t bytesSent = write(m_sockfd, heartbeat, strlen(heartbeat));
if (bytesSent == -1) {
perror("Failed to send heartbeat message");
break;
} else if (bytesSent != static_cast<ssize_t>(strlen(heartbeat))) {
std::cerr << "Partially sent heartbeat message" << std::endl;
}
// 休眠5秒后再发送下一条心跳消息
std::this_thread::sleep_for(std::chrono::seconds(5));
}
}
std::string m_serverIP;
int m_port;
int m_sockfd;
};
int main() {
std::string serverIP = "127.0.0.1"; // 服务器IP地址
int port = 8080; // 服务器监听端口号
TCPClient client(serverIP, port);
client.start();
return 0;
}
//------------------------C++实现的TCP客户端类,并在其中创建了一个线程来每隔5秒发送一次心跳
#include <iostream>
#include <thread>
#include <chrono>
#include <string>
#include <cstdlib> // for exit() function
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
class TCPClient {
private:
int clientSocket;
public:
void connectToServer(const std::string& serverIP, const unsigned short port) {
struct sockaddr_in serverAddress{};
if ((clientSocket = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("Failed to create socket");
exit(-1);
}
serverAddress.sin_family = AF_INET;
serverAddress.sin_port = htons(port);
if (inet_pton(AF_INET, serverIP.c_str(), &serverAddress.sin_addr) <= 0) {
perror("Invalid address or address not supported");
exit(-1);
}
if (connect(clientSocket, reinterpret_cast<struct sockaddr*>(&serverAddress), sizeof(serverAddress)) != 0) {
perror("Connection failed");
exit(-1);
} else {
std::cout << "Connected to the server" << std::endl;
// Start a thread that sends heartbeats every 5 seconds
std::thread sendHeartbeatThread([this](){
while (true) {
char buffer[256];
sprintf(buffer, "heartbeat\n");
if (send(clientSocket, buffer, strlen(buffer), 0) == -1) {
perror("Error sending data");
break;
}
std::this_thread::sleep_for(std::chrono::seconds(5));
}
});
sendHeartbeatThread.detach(); // Detaching the thread allows it to run in background without blocking main program execution
}
}
};
int main() {
TCPClient tcpClient;
tcpClient.connectToServer("服务器IP地址", 8080);
return 0;
}
TcpSocket+发送码流
3. TcpSocket+发送码流+解决组包问题
4. TcpSocket+心跳消息保活链路+发码流+组包不乱序
二、使用步骤
1.引入库
代码如下(示例):
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import warnings
warnings.filterwarnings('ignore')
import ssl
ssl._create_default_https_context = ssl._create_unverified_context
2.读入数据
代码如下(示例):
data = pd.read_csv(
'https://labfile.oss.aliyuncs.com/courses/1283/adult.data.csv')
print(data.head())
该处使用的url网络请求的数据。
总结
提示:这里对文章进行总结:
例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。