WINでのネットワークプログラミング - TCP/IP-Socketプログラミングプロジェクトの実戦、Qtホストコンピュータの構築 - 産業用ロボットのサーバーとクライアント接続(プロジェクトコード付き)

        本稿は、筆者が参加した産業用ロボット2台連携プロジェクトの記録です(詳細は記載しておりません) データ伝送の安定性とセキュリティを考慮し、TCP/IP通信を使用し、上位コンピュータのソフトウェアはC++/Qt (WINDOWS 環境下) を使用して開発され、命令データを送信して下位コンピュータの産業用ロボットを制御し、全体的な組立サイクル計画のために下位コンピュータの信号をフィードバックします。

        この記事はネットワークプログラミングのコラムに含まれているため、ネットワーク通信のコードの一部を記録して解析するだけです。また、この記事はこのコラムで学んだ知識のまとめと検証でもあります。プロジェクトは WINDOWS 環境に基づいているため、 Linux 環境でのソケット プログラミングとは異なります。


        言うことはあまりありません。まずコードを貼り付けます。

サーバー側コード Server.h

#pragma once
#include <stdio.h>
#include <winsock2.h>
#include <iostream>
#include <qobject.h>
#include <QTextStream>
#include<QtCore/qdebug.h>
#pragma comment (lib, "ws2_32.lib")  //加载 ws2_32.dll
const char ip_abb[] = "192.168.125.6"; //ABB IP地址
const char ip_ur[] = "192.168.125.130";//UR IP地址
const char ip_ca[] = "192.168.125.200";

class Server : public QObject {
	Q_OBJECT
private:
	WSADATA wsaData;
	SOCKET serverSock;
	sockaddr_in sockAddr;
	SOCKET clntSock;
	SOCKET abb_clnt;
	SOCKET ur_clnt;
	SOCKET ca_clnt;
	const char *address;

public:
	bool statue;   //0表示未连接,1表示已连接
	bool ca_statue;
	bool ur_statue;
	bool abb_statue;
	int N = 20;
	int port;
	Server(const char *add,int po)
	{
		// 初始化DLL
		statue = 0;
		WSAStartup(MAKEWORD(2, 2), &wsaData);
		//创建套接字
		serverSock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
		clntSock = NULL;
		address = add;
		port = po;
	}

	bool opentolisten()
	{
		int net = 0;
		memset(&sockAddr, 0, sizeof(sockAddr));  //每个字节都用0填充
		sockAddr.sin_family = PF_INET;  //使用IPv4地址
		sockAddr.sin_addr.s_addr = inet_addr(address);  //具体的IP地址
		sockAddr.sin_port = htons(port);  //端口设置 htons为宏定义,主要的作用在于为了避免大小端的问题,
		net = ::bind(serverSock, (SOCKADDR*)&sockAddr, sizeof(SOCKADDR));
		if (net == SOCKET_ERROR)
		{

			qDebug() << "Error #" << WSAGetLastError();
			closesocket(serverSock);
			return false;

		}
		//进入监听状态
		net = listen(serverSock, 20);
		if (net == SOCKET_ERROR)
		{
			qDebug() << "Error #" << WSAGetLastError();
			closesocket(serverSock);

			return false;
		}
		return true;
	}


	bool opentoconect()
	{    		
		int timeout = 1000000;
		
		//接收客户端请求
		SOCKADDR clntAddr;
		int nSize = sizeof(SOCKADDR);
		clntSock = accept(serverSock, (SOCKADDR*)&clntAddr, &nSize);
		if (clntSock != -1)
		{
			statue = 1;
			qDebug() << "服务器接收到一个客户端的连接" ;

			//发送时限
			//setsockopt(clntSock, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(int));
			//接收时限
			//setsockopt(clntSock, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(int));
			//获取地址
			sockaddr_in sin;
			memcpy(&sin, &clntAddr, sizeof(sin));
			const char*p = inet_ntoa(sin.sin_addr);
			QString str = QString(QLatin1String(p));
			qDebug() << str;
			if (!strcmp(p, ip_ca))
			{

				qDebug() << "ca is connected";
				ca_clnt = clntSock;
				ca_statue = 1;
			}
			else if (!strcmp(p, ip_abb))
			{
				qDebug() << "abb is connected";
				abb_clnt = clntSock;
				abb_statue = 1;
			}
			else if (!strcmp(p, ip_ur))
			{
				qDebug() << "ur is connected";
				ur_clnt = clntSock;
				ur_statue = 1;
			}
			return true;
		}
		else
		{
			statue = 0;
			return false;
		}

	}

	void calver(char * inmsg)
	{
		char ver = 0;
		for (int i = 1; i < N - 2; i++)
		{
			ver = ver + inmsg[i];
		}
		inmsg[N - 2] = ver;
		inmsg[N - 1] = 0xCC;
	}


	bool sendmes(char *message, int nlen)
	{
		//计算验证位
		calver(message);
		int sendnum = 0;
		if (statue)
		{
			sendnum = send(clntSock, message, nlen, 0);
			return true;
		}
		else
		{
			return false;
		}
	}

	bool readmes(char * message, int nlen)
	{
		int readnum = 0;
		if (statue)
		{
			readnum = recv(clntSock, message, nlen, 0);
			if (readnum > 0)
				return true;
			else
				return false;
		}
		else
		{
			return false;
		}
	}

	bool closetcp()
	{
		if(clntSock!=NULL)
			closesocket(clntSock);
		return true;
	}


	bool ca_sendmes(char *message, int nlen)
	{
		int sendnum = 0;
		if (ca_statue)
		{
			sendnum = send(ca_clnt, message, nlen, 0);
			return true;
		}
		else
		{
			return false;
		}
	}

	bool abb_sendmes(char *message, int nlen)
	{
		int sendnum = 0;
		if (abb_statue)
		{
			sendnum = send(abb_clnt, message, nlen, 0);
			return true;
		}
		else
		{
			return false;
		}
	}

	bool ur_sendmes(char *message, int nlen)
	{
		int sendnum = 0;
		if (ur_statue)
		{
			sendnum = send(ur_clnt, message, nlen, 0);
			return true;
		}
		else
		{
			return false;
		}
	}


	bool ca_readmes(char * message, int nlen)
	{
		int readnum = 0;
		if (ca_statue)
		{
			readnum = recv(ca_clnt, message, nlen, 0);
			if (readnum > 0)
				return true;
			else
				return false;
		}
		else
		{
			return false;
		}
	}

	bool ur_readmes(char * message, int nlen)
	{
		int readnum = 0;
		if (ur_statue)
		{
			readnum = recv(ur_clnt, message, nlen, 0);
			if (readnum > 0)
				return true;
			else
				return false;
		}
		else
		{
			return false;
		}
	}

	bool abb_readmes(char * message, int nlen)
	{

		int readnum = 0;
		if (abb_statue)
		{
			readnum = recv(abb_clnt, message, nlen, 0);
			if (readnum > 0)
				return true;
			else
				return false;
		}
		else
		{
			return false;
		}
	}
};

opentolisten()opentoconect()の2 つのメンバー関数は        主に通信機能を実現しており、それぞれサーバーを作成し、サーバーをリッスン状態にしてクライアントの接続を待機する機能があります。

bool opentolisten()

	bool opentolisten()
	{
		int net = 0;
		memset(&sockAddr, 0, sizeof(sockAddr));  //每个字节都用0填充
		sockAddr.sin_family = PF_INET;  //使用IPv4地址
		sockAddr.sin_addr.s_addr = inet_addr(address);  //具体的IP地址
		sockAddr.sin_port = htons(port);  //端口设置 htons为宏定义,主要的作用在于为了避免大小端的问题,
		net = ::bind(serverSock, (SOCKADDR*)&sockAddr, sizeof(SOCKADDR));
		if (net == SOCKET_ERROR)
		{
			qDebug() << "Error #" << WSAGetLastError();
			closesocket(serverSock);
			return false;
		}
		//进入监听状态
		net = listen(serverSock, 20);
		if (net == SOCKET_ERROR)
		{
			qDebug() << "Error #" << WSAGetLastError();
			closesocket(serverSock);

			return false;
		}
		return true;
	}

bool opentoconect()

	bool opentoconect()
	{    
		
		int timeout = 1000000;
		
		//接收客户端请求
		SOCKADDR clntAddr;
		int nSize = sizeof(SOCKADDR);
		clntSock = accept(serverSock, (SOCKADDR*)&clntAddr, &nSize);
		if (clntSock != -1)
		{
			statue = 1;
			qDebug() << "服务器接收到一个客户端的连接" ;

			//发送时限
			//setsockopt(clntSock, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(int));
			//接收时限
			//setsockopt(clntSock, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(int));
			//获取地址
			sockaddr_in sin;
			memcpy(&sin, &clntAddr, sizeof(sin));
			const char*p = inet_ntoa(sin.sin_addr);
			QString str = QString(QLatin1String(p));
			qDebug() << str;
			if (!strcmp(p, ip_ca))
			{

				qDebug() << "ca is connected";
				ca_clnt = clntSock;
				ca_statue = 1;
			}
			else if (!strcmp(p, ip_abb))
			{
				qDebug() << "abb is connected";
				abb_clnt = clntSock;
				abb_statue = 1;
			}
			else if (!strcmp(p, ip_ur))
			{
				qDebug() << "ur is connected";
				ur_clnt = clntSock;
				ur_statue = 1;
			}

			return true;
		}
		else
		{
			statue = 0;
			return false;
		}

	}

おすすめ

転載: blog.csdn.net/cj_lsk/article/details/131090521