• windows核心编程之网络编程入门篇




    来源:微信公众号「编程学习基地」

    大端小端

    大端模式指数据的高字节保存在内存的低地址

    例如:12345( 0x3039 ) 的存储顺序是 0x30、0x39

    小端模式指数据的高字节保存在内存的高地址

    例如:12345( 0x3039 ) 的存储顺序是 0x39、0x30

    判断大小端

    方法一:

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

    方法二:

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

    方法三:

    #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("小端
    ");
    	}
    	else
    	{
    		printf("大端
    ");
    	}
    	return 0;
    }
    

    CS模型

    在这里插入图片描述

    Socket网络编程

    WSAStartup / WSACleanup

    int WSAStartup ( WORD wVersionRequested,
                    LPWSADATA pWSAData );
    

    每一个WSAStartup都不许对应一个WSACleanup的调用

    socket

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

    WinSock只支持AF_INET

    • type:

    SOCK_STREAMSOCK_DGRAMSOCK_RAW等等

    • protocol:

    如果type为SOCK_STREAM,使用的是tcp协议

    如果type为SOCK_DGRAM,使用的是udp协议

    此时protocol可以指定为0

    如果type为SOCK_RAW,使用的是原始套接字,protocol可以去自定义协议,例如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;
    }
    

    点分十进制转换

    inet_addr()

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

    in_addr_t inet_addr(const char* cp);
    
    • 参数:字符串,一个点分十进制的IP地址
    • 返回值:
      若字符串有效,则将字符串转换为32位二进制网络字节序的IPV4地址;否则,为INADDR_NONE

    inet_ntoa()

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

    char *inet_ntoa(struct in_addr);
    
    • 参数:in_addr是一个结构体,用来表示一个32位的IPV4地址
    • 返回值:返回点分十进制的字符串在静态内存中的指针

    端口转化函数

    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来进行端口转换

    bind

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

    listen

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

    accept

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

    connect

    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() 
    ");
    		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() 
    ");
    		WSACleanup();
    		return 0;
    	}
    
    	// 进入监听模式
    	if (listen(s, 2) == SOCKET_ERROR)		//最大连接数为2
    	{
    		printf("Failed listen()");
    		WSACleanup();
    		return 0;
    	}
    	printf("Start listen:
    ");
    	// 循环接受客户的连接请求
    	sockaddr_in remoteAddr;
    	int nAddrLen = sizeof(remoteAddr);
    	SOCKET client;
    	char szText[] = "hello!
    ";
    	while (TRUE)
    	{
    		// 接受一个新连接
    		client = accept(s, (SOCKADDR*)&remoteAddr, &nAddrLen);
    		if (client == INVALID_SOCKET)
    		{
    			printf("Failed accept()");
    			continue;
    		}
    
    		printf(" 接受到一个连接:%s 
    ", 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() 
    ");
    		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() 
    ");
    		WSACleanup();
    		return 0;
    	}
    
    	// 接收数据
    	char buff[256];
    	int nRecv = recv(s, buff, 256, 0);
    	if (nRecv > 0)
    	{
    		buff[nRecv] = '';
    		printf(" 接收到数据:%s", buff);
    	}
        
    	// 关闭套节字
    	closesocket(s);
    	// 释放WS2_32库
    	WSACleanup();
    	return 0;
    }
    
  • 相关阅读:
    webservice的两种客户端调用方式(总结)
    Maven笔记
    在myeclipse中建立webservice,发布webservice并且调用webservice接口
    1分钟内使用Adobe Dreamweaver CS5建立导航菜单
    Asp.Net Cookie的清除
    常用的sql标准建表语句
    Java5的 线程并发库
    使用NPOI操作Excel
    使用.net 内置的SmtpClient来实现邮件的发送
    qlikview 地图插件制作教程
  • 原文地址:https://www.cnblogs.com/deroy/p/14067346.html
Copyright © 2020-2023  润新知