Windowsコアプログラミングのネットワークプログラミング入門

ここに画像の説明を挿入

出典:WeChat公式アカウント「プログラミング学習ベース」

ビッグエンドリトルエンド

ビッグエンディアンモード指数据的高字节保存在内存的低地址

例:12345(0x3039)の保管順序は 0x30、0x39

リトルエンディアンモード指数据的高字节保存在内存的高地址

例:12345(0x3039)の保管順序は 0x39、0x30

ビッグエンドを判断する

方法1:

#include<stdio.h>
int main(int argc, char *argv[])
{
    
    
	int i = 0x12345678;
	char c = i;
	if (c == 0x78)
	{
    
    
		printf("小端\n");
	}
	else
	{
    
    
		printf("大端\n");
	}
	return 0;
}

方法2:

#include<stdio.h>
int main(void)
{
    
    
	int  a = 0x12345678;
	char *p = (char *)&a;
	if (0x78 == *p)
	{
    
    
		printf("小端\n");
	}
	else
	{
    
    
		printf("大端\n");
	}
	return 0;
}

方法3:

#include<stdio.h>
typedef union NODE
{
    
    
	int i;
	char c;
}Node;
int main(int argc, char *argv[])
{
    
    
	Node node;
	node.i = 0x12345678;
	if (0x78 == node.c)
	{
    
    
		printf("小端\n");
	}
	else
	{
    
    
		printf("大端\n");
	}
	return 0;
}

CSモデル

ここに画像の説明を挿入

ソケットネットワークプログラミング

WSAStartup / WSACleanup

int WSAStartup ( WORD wVersionRequested,
                LPWSADATA pWSAData );

それぞれが1WSAStartupつのWSACleanup呼び出しに対応することは許可されていません

ソケット

int socket(int af,
           int type,
           int protocol);
  • AF:AF_INETAF_INET6AF_LOCAL

WinSockはサポートのみAF_INET

  • タイプ:

SOCK_STREAMSOCK_DGRAMSOCK_RAW

  • プロトコル:

タイプがのSOCK_STREAM場合、tcpプロトコルが使用されます

タイプがのSOCK_DGRAM場合、udpプロトコルが使用されます

現時点ではprotocol0として指定できます

タイプがのSOCK_RAW場合、元のソケットが使用され、ICMPやその他のプロトコルなどのプロトコルをカスタマイズできます。

sockaddr_in

struct sockaddr_in {
    
     
   short int sin_family,		//地址家族
	unsigned short int sin_port, //端口号
    struct in_addr sin_addr,	//IP地址
    unsigned char sin_zero[8],	//空字节,设为0
}   

struct in_addr:

struct in_addr{
    
     
	unsigned long s_addr;
}

ドット付き10進変換

inet_addr()

将一个点分十进制字符串转化为二进制的数

in_addr_t inet_addr(const char* cp);
  • パラメータ:文字列、ドット付き10進IPアドレス
  • 戻り値:
    文字列が有効な場合、文字列は32ビットのバイナリネットワークバイトオーダーIPV4アドレスに変換されます。それ以外の場合は、INADDR_NONEになります。

inet_ntoa()

将二进制数转换为一个点分十进制字符串

char *inet_ntoa(struct in_addr);
  • パラメータ:in_addrは、32ビットIPV4アドレスを表すために使用される構造体です。
  • 戻り値:スタティックメモリ内のドット付き10進文字列のポインタを返します

ポート変換機能

TCP / IPプロトコルは、ネットワークのバイト順序、つまりビッグエンディアンを一律に使用します。

u_short htons(u_short hostshurt)	//主机字节顺序转网络字节顺序
u_long htonl(u_long hostshurt)		//主机字节顺序转网络字节顺序
u_short ntohs(u_short hostshurt)	//网络字节顺序转主机字节顺序
u_long ntohl(u_long hostshurt)		//网络字节顺序转主机字节顺序

通常htons、ポート変換に使用されます

練る

int bind(
	SOCKET s,						//套接字句柄
	onst struct sockaddr* name,		//本地地址
	int namelen						//地址长度
); 

聴く

int listen(
	SOCKET s,		//套接字句柄
	int backlog		//监听队列允许保持的最大连接数量
);

受け入れる

SOCKET accept(
	SOCKET s,			//套接字句柄
	struct sockaddr* addr,	//协议族渎职
	int* addrlen			//地址长度
);

接続する

int connect(
	SOCKET s,	//套接字句柄
	const struct sockaddr* name,	//协议族地址
 	int namelen						//地址长度
);

tcpサーバー

#include <winsock2.h>	// 为了使用Winsock API函数
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>

// 告诉连接器与WS2_32库连接
#pragma comment(lib,"WS2_32.lib")

int main(int argc, char* argv[])
{
    
    
	// 初始化WS2_32.dll
	WSADATA wsaData;
	WORD sockVersion = MAKEWORD(2, 2);
	WSAStartup(sockVersion, &wsaData);	//请求了一个2.2版本的socket

	// 创建套节字
	SOCKET s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (s == INVALID_SOCKET)
	{
    
    
		printf("Failed socket() \n");
		WSACleanup();
		return 0;
	}

	// 填充sockaddr_in结构
	sockaddr_in sin;
	sin.sin_family = AF_INET;				
	sin.sin_port = htons(8888);				//8888端口
	//sin.sin_addr.S_un.S_addr = INADDR_ANY;	//本地地址 
	sin.sin_addr.S_un.S_addr = inet_addr("169.254.211.52"); //172.19.12.44

	// 绑定这个套节字到一个本地地址
	if (bind(s, (LPSOCKADDR)&sin, sizeof(sin)) == SOCKET_ERROR)
	{
    
    
		printf("Failed bind() \n");
		WSACleanup();
		return 0;
	}

	// 进入监听模式
	if (listen(s, 2) == SOCKET_ERROR)		//最大连接数为2
	{
    
    
		printf("Failed listen()");
		WSACleanup();
		return 0;
	}
	printf("Start listen:\n");
	// 循环接受客户的连接请求
	sockaddr_in remoteAddr;
	int nAddrLen = sizeof(remoteAddr);
	SOCKET client;
	char szText[] = "hello!\n";
	while (TRUE)
	{
    
    
		// 接受一个新连接
		client = accept(s, (SOCKADDR*)&remoteAddr, &nAddrLen);
		if (client == INVALID_SOCKET)
		{
    
    
			printf("Failed accept()");
			continue;
		}

		printf(" 接受到一个连接:%s \r\n", inet_ntoa(remoteAddr.sin_addr));

		// 向客户端发送数据
		send(client, szText, strlen(szText), 0);

		// 关闭同客户端的连接
		closesocket(client);
	}

	// 关闭监听套节字
	closesocket(s);
	// 释放WS2_32库
	WSACleanup();

	return 0;
}

tcpクライアントアドレス

#include <winsock2.h>	
#include <stdio.h>
#include <windows.h>

// 告诉连接器与WS2_32库连接
#pragma comment(lib,"WS2_32.lib")

int main(int argc, char* argv[])
{
    
    
	// 初始化WS2_32.dll
	WSADATA wsaData;
	WORD sockVersion = MAKEWORD(2, 2);
	WSAStartup(sockVersion, &wsaData);

	// 创建套节字
	SOCKET s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (s == INVALID_SOCKET)
	{
    
    
		printf("Failed socket() \n");
		WSACleanup();
		return 0;
	}

	// 填写远程地址信息
	sockaddr_in servAddr;
	servAddr.sin_family = AF_INET;
	servAddr.sin_port = htons(8888);
	// 如果你的计算机没有联网,直接使用本地地址127.0.0.1
	servAddr.sin_addr.S_un.S_addr = inet_addr("169.254.211.52");

	if (connect(s, (sockaddr*)&servAddr, sizeof(servAddr)) == -1)
	{
    
    
		printf("Failed connect() \n");
		WSACleanup();
		return 0;
	}

	// 接收数据
	char buff[256];
	int nRecv = recv(s, buff, 256, 0);
	if (nRecv > 0)
	{
    
    
		buff[nRecv] = '\0';
		printf(" 接收到数据:%s", buff);
	}
    
	// 关闭套节字
	closesocket(s);
	// 释放WS2_32库
	WSACleanup();
	return 0;
}

おすすめ

転載: blog.csdn.net/qq_44519484/article/details/108754724