Linux-Remote-Entwicklung - Netzwerkkommunikation (der Client stellt eine Verbindung zum Server her)

Inhalt

I. Einleitung

Zweitens die drei Elemente der Netzwerkprogrammierung

1. IP-Adresse

1) IP-Adresskonzept

2) Greifen Sie über die IP-Adresse auf die offizielle CSDN-Website zu

3) Lokale Loopback-IP-Adresse 127.0.0.1

2. Portnummer

3. Kommunikationsprotokoll

1) Konzept des Kommunikationsprotokolls

2) TCP und UDP

3. Grundlegende Programmierung der Netzwerkkommunikation

1. Programmiervorgang

2. Erstellen Sie einen lokalen Server

1) socket() initialisiert das Netzwerk

2) bind()-Funktion

3) listen() Listener-Funktion

4) Accept()-Funktion

5) Alle Servercodes

3. Erstellen Sie einen Kunden

4. Test des Client-Verbindungsservers


I. Einleitung

        Dieser Artikel führt in die Grundlagen der Netzwerkprogrammierung ein, verwendet Visual Studio 2019 , um einen Server lokal in Linux zu erstellen , verbindet den Client mit dem lokalen Server, sendet Informationen über den Client an den Server und testet, ob der Server Informationen empfangen kann.

  • Lassen Sie uns vor dem Programmieren einige Grundlagen verstehen

Zweitens die drei Elemente der Netzwerkprogrammierung

Die drei Elemente der Netzwerkprogrammierung bestehen aus den folgenden drei Punkten:

1. IP-Adresse : Bestimmen Sie den Standort eines Computers im Netzwerk

2. Portnummer : Bestimmen Sie, um welche spezifische Anwendung es sich handelt

3. Kommunikationsprotokoll : eine Vereinbarung, die von beiden Parteien in der Kommunikation vereinbart und befolgt wird

1. IP-Adresse

1) IP-Adresskonzept

  • Die IP-Adresse wird verwendet, um zu unterscheiden, um welches Computergerät es sich handelt.Nur durch Kenntnis der IP-Adresse des Geräts der anderen Partei kann der Computerder anderen Partei gefunden werden.    

       IP-Adressen sind wie unsere Privatadressen. Wenn Sie einer Person einen Brief schreiben, müssen Sie ihre Adresse kennen, damit der Postbote den Brief zustellen kann. Ein Computer ist beim Versenden von Informationen wie ein „ Postbote “, er muss eine eindeutige „ Heimadresse “ kennen, um den Brief nicht an die falsche Person zu senden.

        Dieselbe Netzwerkprogrammierung erfordert auch die Verwendung von IP-Adressen.Der Client muss die IP-Adresse des Servers kennen, um den Server zu finden,zu dem die Verbindung aufgebaut werden muss. Tatsächlich hat die Webseite auch ihre entsprechende IP-Adresse.Wir suchen normalerweise nach Dingen, indem wir den Domänennamen eingeben, um darauf zuzugreifen, oder Sie können die IP-Adresse eingeben, um darauf zuzugreifen.

2) Greifen Sie über die IP-Adresse auf die offizielle CSDN-Website zu

Beispiel: Die offizielle Website von csdn ist www.csdn.net

  • Öffnen Sie im Fenster das Ausführungsfeld, indem Sie win+r drücken, cmd eingeben und die Eingabetaste drücken
  • Konsoleneingabe ping www.csdn.net

  • Die Browsereingabe 39.106.226.142 kann auch die offizielle CSDN-Website besuchen

        Es kann festgestellt werden, dass dem Domänennamen eine IP-Adresse folgt, und der Browser kann auch auf die offizielle CSDN-Website zugreifen, indem er diese IP-Adresse eingibt. Tatsächlich sind der Domänenname und die IP-Adresse ein eindeutiges Schlüssel-Wert-Paar . Ist es unbequem, eine so lange IP-Adresse einzugeben, um auf die offizielle CSDN-Website zuzugreifen, sodass der Domänenname zu diesem Zeitpunkt angezeigt wird, ist es bequemer, den Domänennamen für den Zugriff zu verwenden.

3) Lokale Loopback-IP-Adresse 127.0.0.1

  • Die IP-Adresse des lokalen Servers kann auf 127.0.0.1 eingestellt werden

        127.0.0.1 , allgemein als lokale Loopback-Adresse bezeichnet, gehört zu keiner klassenbasierten Adressklasse. Es stellt die lokale virtuelle Schnittstelle des Geräts dar und wird daher standardmäßig als Schnittstelle betrachtet, die niemals ausfällt. Im Windows-Betriebssystem gibt es eine ähnliche Definition, sodass diese lokale Loopback-Adresse normalerweise vor der Installation der Netzwerkkarte angepingt werden kann.

2. Portnummer

  • Wenn Sie nur die IP-Adresse kennen, können Sie nur einen bestimmten Computer finden.Um eine Anwendung zu finden, müssen Sie die Portnummer kennen.

        Einfach ausgedrückt ist die Portnummer die Kennung des laufenden Programms , die zur Unterscheidung der spezifischen Anwendung verwendet wird.

3. Kommunikationsprotokoll

1) Konzept des Kommunikationsprotokolls

  • Der Aufbau einer Kommunikation erfordert auch Kommunikationsprotokolle, wie z. B. Chinesisch, die einheitliche Sprache Chinas , damit die Kommunikation einfach ist

        Das Kommunikationsprotokoll bezieht sich auf die Regeln und Konventionen, die von beiden Einheiten befolgt werden müssen, um die Kommunikation oder Dienste abzuschließen . Mehrere Datenkommunikationssysteme an verschiedenen geografischen Standorten, die durch Kommunikationskanäle und -geräte miteinander verbunden sind, müssen eine gemeinsame Sprache haben, damit sie zusammenarbeiten, um einen Informationsaustausch und eine gemeinsame Nutzung von Ressourcen zu erreichen. Was kommuniziert wird, wie kommuniziert wird und wann kommuniziert wird, muss bestimmten gegenseitig akzeptablen Regeln folgen. Diese Regel ist das Kommunikationsprotokoll.

2) TCP und UDP

  • Die aktuellen ausgereiften Kommunikationsprotokolle sind TCP und UDP, und die Vorgänger anderer Protokolle sind TCP oder UDP

  • Werfen wir einen Blick auf den Unterschied zwischen den beiden Protokollen
TCP UDP
Ob eine Verbindung aufgebaut werden muss Zum Senden von Informationen ist eine Verbindung erforderlich Es ist keine Verbindung erforderlich
Übertragungsmedium Streaming IO (binäre Daten) Daten werden in Pakete gekapselt
Übertragungsbeschränkungen Big-Data-Übertragung möglich Es können jeweils nur 64 KB übertragen werden
Zusammenfassen Einbußen bei der Effizienz, Verbesserung der Übertragungssicherheit, zuverlässiges Protokoll Eingeschränkte Sicherheit, Verbesserung der Übertragungseffizienz, unzuverlässiges Protokoll
  • Das OSI-Referenzmodell und das TCP/IP-Referenzmodell sind in der folgenden Abbildung dargestellt 

Als nächstes verwenden wir das TCP-Protokoll, um die Verbindung zwischen dem Server und dem Client über den Code herzustellen.

Mann der wenigen Worte

 

3. Grundlegende Programmierung der Netzwerkkommunikation

1. Programmiervorgang

  • Der Programmierfluss basierend auf Stream-Socket ist in der folgenden Abbildung dargestellt

        Dieser Artikel beschreibt, dass, nachdem der Client eine Verbindung mit dem Server hergestellt hat, der Client schreibt (), der Server liest (), und zuerst ein einfacher Verbindungstest durchgeführt wird, und der Client und der Server später miteinander kommunizieren. Die nächste Programmierung wird gemäß dem obigen Prozess ausgeführt.

2. Erstellen Sie einen lokalen Server

1) socket() initialisiert das Netzwerk

int socketfd = 0;
//初始化网络  参数一:使用ipv4  参数二:流式传输
socketfd = socket(AF_INET, SOCK_STREAM, 0);
  • socket() Netzwerkinitialisierung, gibt Dateideskriptor zurück

Funktionsprototyp:

int socket (int Domäne, int Typ, int Protokoll);

Rückgabewert:

Erfolg: Dateideskriptor zurückgeben

Fehler: Rückgabe -1

  • Der erste Parameter verwendet AF_INET, also IPv4

  • Der zweite Parameter ist SOCK_STREAM, ein Streaming-Socket

  • Der dritte Parameter ist 0

2) bind()-Funktion

  • Binden Sie die IP-Adresse und Portnummer und bestimmen Sie das Kommunikationsprotokoll als ipv4
//原本使用struct sockaddr,通常使用sockaddr_in更为方便,两个数据类型是等效的,可以相互转换
struct sockaddr_in s_addr;
//确定使用哪个协议族  ipv4
s_addr.sin_family = AF_INET;

//系统自动获取本机ip地址 也可以是本地回环地址:127.0.0.1
s_addr.sin_addr.s_addr = INADDR_ANY;

//端口一个计算机有65535个  10000以下是操作系统自己使用的,  自己定义的端口号为10000以后
s_addr.sin_port = htons(12345);  //自定义端口号为12345

len = sizeof(s_addr);

//绑定ip地址和端口号
int res = bind(socketfd, (struct sockaddr *)&s_addr, len);
if (res == -1)
{
	perror("bind error");
}

Funktionsprototyp:

int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

Rückgabewert:

Erfolg: Rückgabe 0

Fehler: Rückgabe -1

  • Der erste Parameter verwendet den vom vorherigen Schritt zurückgegebenen Dateideskriptor 
  • Der zweite Parameter verwendet stattdessen die Struktur struct sockaddr_in, was praktischer ist
  • Der dritte Parameter ist die Größe der Struktur struct sockaddr_in

3) listen() Listener-Funktion

  • Überwachen, ob Clients eine Verbindung herstellen
//监听这个地址和端口有没有客户端来连接  第二个参数现在没有用  只要大于0就行
if (listen(socketfd, 2) == -1)
{
	perror("listen error");
}

Funktionsprototyp:

int listen(int sockfd, int backlog);

Rückgabewert:

Erfolg: Rückgabe 0

Fehler: Rückgabe -1

  • Der erste Parameter ist der zuvor erhaltene Serverdateideskriptor
  • Der zweite Parameter muss nur > 0 sein 

4) Accept()-Funktion

  • Warten, bis der Client online geht, Sperrfunktion , nur wenn der Client online geht, wird er weiter ausgeführt

        Durch eine Weile (1) Endlosschleife bleibt der Server online und wartet darauf, dass der Client online geht.Sobald ein Client online geht, wird ein untergeordneter Prozess geöffnet und die vom Client gesendete Nachricht wird in einer Schleife im untergeordneten Prozess gelesen Prozess. Der übergeordnete Prozess wartet weiterhin darauf, dass der nächste Client online kommt.

Notiz:

Die read()-Funktion ist auch eine blockierende Funktion .

//死循环保证服务器一直在线
while (1)
{
	cout << "等待客户端上线" << endl;
	//等待客户端上线,阻塞式函数  acceptfd为连上来的客户端fd
	acceptfd = accept(socketfd, NULL, NULL);
	cout << "客户端上线 fd = " << acceptfd << endl;
	pid = fork();
	if (pid == 0)//子进程  持续读取客户端发来的信息
	{
		while (1)
		{
			read(acceptfd, buf, sizeof(buf));
			cout << "pid = " << getpid() << " 说: " << buf << endl;
			bzero(buf, sizeof(buf));
		}
	}
}

Funktionsprototyp:

int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

Rückgabewert:

Erfolg: Client-Dateideskriptor zurückgeben

Fehler: Rückgabe -1

  • Der erste Parameter ist der zuvor erhaltene Serverdateideskriptor
  • Der zweite dritte Parameter kann als NULL angegeben werden 

5) Alle Servercodes

#include <iostream>
#include <sys/types.h>         
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
using namespace std;

int main()
{
	
	int socketfd = 0;
	int acceptfd = 0;
	int len = 0;
	int pid = 0;
	char buf[255] = { 0 };//存放客户端发过来的信息
	//初始化网络  参数一:使用ipv4  参数二:流式传输
	socketfd = socket(AF_INET, SOCK_STREAM, 0);
	if (socketfd == -1)
	{
		perror("socket error");
	}
	else
	{
		//原本使用struct sockaddr,通常使用sockaddr_in更为方便,两个数据类型是等效的,可以相互转换
		struct sockaddr_in s_addr;
		//确定使用哪个协议族  ipv4
		s_addr.sin_family = AF_INET;

		//系统自动获取本机ip地址 也可以是本地回环地址:127.0.0.1
		s_addr.sin_addr.s_addr = INADDR_ANY;

		//端口一个计算机有65535个  10000以下是操作系统自己使用的,  自己定义的端口号为10000以后
		s_addr.sin_port = htons(12345);  //自定义端口号为12345

		len = sizeof(s_addr);

		//绑定ip地址和端口号
		int res = bind(socketfd, (struct sockaddr *)&s_addr, len);
		if (res == -1)
		{
			perror("bind error");
		}
		else
		{
			//监听这个地址和端口有没有客户端来连接  第二个参数现在没有用  只要大于0就行
			if (listen(socketfd, 2) == -1)
			{
				perror("listen error");
			}
			//死循环保证服务器一直在线
			while (1)
			{
				cout << "等待客户端上线" << endl;
				//等待客户端上线,阻塞式函数  acceptfd为连上来的客户端fd
				acceptfd = accept(socketfd, NULL, NULL);
				cout << "客户端上线 fd = " << acceptfd << endl;
				pid = fork();
				if (pid == 0)//子进程  持续读取客户端发来的信息
				{
					while (1)
					{
						read(acceptfd, buf, sizeof(buf));
						cout << "pid = " << getpid() << " 说: " << buf << endl;
						bzero(buf, sizeof(buf));
					}
				}
			}
		}
	}
}

3. Erstellen Sie einen Kunden

  • Die Clientseite muss nur socket() ausführen, um das Netzwerk zu initialisieren, und die IP-Adresse und Portnummer binden, um das Kommunikationsprotokoll ipv4 zu bestimmen
#include <iostream>
#include <sys/types.h>          
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
using namespace std;

int main()
{
	int socketfd = 0;
	int acceptfd = 0;
	int len = 0;
	char buf[255] = { 0 };
	//初始化网络
	socketfd = socket(AF_INET, SOCK_STREAM, 0);
	if (socketfd == -1)
	{
		perror("socket error");
	}
	else
	{
		struct sockaddr_in s_addr;
		//确定使用哪个协议族  ipv4
		s_addr.sin_family = AF_INET;

		//填入服务器的ip地址  也可以是  127.0.0.1 (回环地址)
		s_addr.sin_addr.s_addr = inet_addr("127.0.0.1");

		//端口一个计算机有65535个  10000以下是操作系统自己使用的,  自己定义的端口号为10000以后
		s_addr.sin_port = htons(12345);  //自定义端口号为12345

		len = sizeof(s_addr);

		//绑定ip地址和端口号
		int res = connect(socketfd, (struct sockaddr*)&s_addr, len);
		if (res == -1)
		{
			perror("connect error");
		}
		else
		{
			while (1)
			{
				//控制台输入
				fgets(buf, sizeof(buf), stdin);
				write(socketfd, buf, sizeof(buf));
				bzero(buf, sizeof(buf));
			}
		}
	}
	return 0;
}

Notiz:

1. Da es sich um einen lokalen Client handelt und der Server ebenfalls lokal ist, kann die gebundene IP-Adresse die lokale Loopback-Adresse sein .

2. Die gebundene Portnummer und das verwendete Kommunikationsprotokoll müssen mit denen des Servers übereinstimmen

3. Der Dateideskriptor in der Funktion write() ist der des Servers

4. Test des Client-Verbindungsservers

  • Finden Sie die entsprechende main.cpp unter Linux, kompilieren Sie sie mit g++ und führen Sie ./ aus.

Notiz:

1. Wenn der Code geändert wird, muss die Lösung neu generiert werden, und der Code kann mit Linux synchronisiert werden

2. Führen Sie zuerst den Server und dann den Client aus

Testergebnisse

        Es kann festgestellt werden, dass der Server jedes Mal, wenn ein Client ausgeführt wird, eine Eingabeaufforderung erhält und die vom Client gesendeten Informationen vom Server empfangen werden können, was anzeigt, dass die Verbindung zwischen dem Client und dem Server erfolgreich ist! !

Originalität ist nicht einfach, bei Nachdruck bitte Quelle angeben.

Wenn es für Sie hilfreich ist, können Sie dreimal klicken, und es wird ständig aktualisiert (hihi).

Supongo que te gusta

Origin blog.csdn.net/wmcy123/article/details/123762635
Recomendado
Clasificación