TCP/IP网络通信 WinSock编程

网络字节顺序:

网络中传输的数据使用的均是大尾方式, 大尾方式是 高位存放低字节,地位存放高字节。

windows提供了一些函数来处理本地机器的字节顺序和网络字节顺序的转换:

	u_short htons(u_short hostshort);
   	u_long htonl(u_long hostlong);
	u_short ntohs(u_short netshort);
	u_long ntohl(u_long netlong);


这些API是平台无关的,使用它们可以正确运行在所有机器上

网络编程基础:

每个使用Winsock进行网络开发的Windows应用程序都必须包含Winsock2.h,另外还需要一个静态库ws2_32.lib。在使用它们的时候需要对这个库进行一次初始化,使用完后要对该库进行释放。

1.初始化ws2_32.dll 动态链接库的函数: WSAStartup()

2.释放ws2_32.dll的函数: WSACleanup()

3.加载ws2_32.lib :  #pragma comment (lib, "ws2_32")  //指明要链接到ws2_32.lib 

.dll 文件就是动态链接库,.lib 文件是提供程序开发用的导入库, .h文件包含了导出函数的声明

 一个简单的通信例子:

服务器端:

//#include <Windows.h>	//不要加进来!!!
#include <iostream>
#include <string.h>
#include <WinSock2.h>	//winsock2.h 和 windows.h的顺序不要反
#include <Windows.h>
#pragma comment (lib, "ws2_32.lib")
#pragma comment (lib, "winmm.lib")	//用于支持 mci device
using namespace std;

//帮助命令宏
#define HELPMSG "help - Show Help Menu \r\n"\
	"getsysinfo - Get SysTem Information \r\n"\
	"open - Open The CDRom \r\n"\
	"close - Close The CDRom \r\n"\
	"swap - Swap Mouse Button \r\n"\
	"restore - Restore Mouse Button \r\n"\
	"exit - Quit BdShell"

#define NAME_LEN 20
//保存获取的系统信息
typedef struct _SYS_INFO
{
	OSVERSIONINFO OsVer;				//保存操作系统的信息
	char szComputerName[NAME_LEN];		//保存计算机名称
	char szUserName[NAME_LEN];			//保存当前登录名称
}SYS_INFO, *PSYS_INFO;

//函数声明
BOOL Dispatch(SOCKET, char *);		//分发命令
void GetSysInfo(SYS_INFO *);		//获得系统信息
void SetCdaudio(BOOL);				//打开或者关闭光驱
void SetMouseButton(BOOL);			//交换或者恢复鼠标左右键功能

int main()
{
	WSADATA wsaData;	//保存DLL库的详细信息
	::WSAStartup(MAKEWORD(2,2), &wsaData);

	//创建套接字
	SOCKET s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);

	sockaddr_in sockaddr;
	sockaddr.sin_family = PF_INET;	//地址家族 PF_INET指互联网地址家族(TCP/IP)
	//如果IP地址为 INADDR_ANY 系统会自动使用当前主机配置的所有IP地址
	sockaddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); //IP地址
	sockaddr.sin_port = htons(8008);	//端口号

	//绑定套接字到指定的IP地址和端口号
	::bind(s, (SOCKADDR*)&sockaddr, sizeof(SOCKADDR));

	//进入监听模式
	::listen(s, 1);	//1 表示监听队列中允许保持的尚未处理的最大连接数量

	//保存客户端的信息
	sockaddr_in clientAddr;
	int nSize = sizeof(SOCKADDR);
	//用于取的对方的地址信息
	SOCKET clientSock;

	printf("服务器已启动...\n");
	//接受连接请求
	clientSock = ::accept(s, (SOCKADDR*)&clientAddr, &nSize);

	while(TRUE)
	{
		
		//发送一个命令提示
		::send(clientSock, "BdShell>", strlen("BdShell>") + sizeof(char), 0);
		
		char buff[MAXBYTE] = {0};

		//接收客户端发来的命令
		::recv(clientSock, buff, MAXBYTE, 0);
		if(!strcmp(buff, "exit"))
			break;
		//分发命令
		BOOL bRet = Dispatch(clientSock, buff);
		if(bRet == FALSE)
		{
			::send(clientSock, "Commend Unsuccessfully", 
				strlen("Commend Unsuccessfully") + sizeof(char), 0);
			printf("next->\n");
		}
		else 
		{
			::send(clientSock, "Commend successfully",
				strlen("Comment successfully") + sizeof(char), 0);
			printf("next->\n");
		}
	}
	closesocket(clientSock);
	closesocket(s);
	WSACleanup();
	return 0;
}

BOOL Dispatch(SOCKET sock, char * szCmd)
{
	BOOL bRet = FALSE;
	//根据不同的命令,完成不同的功能
	if(!strcmp(szCmd, "help"))
	{
		//
		::send(sock, HELPMSG, strlen(HELPMSG) + sizeof(char), 0);
		bRet = TRUE;
	}
	//获取系统信息
	else if(!strcmp(szCmd, "getsysinfo"))
	{
		//
		SYS_INFO sysInfo = {0};
		GetSysInfo(&sysInfo);
		printf("%s\n", (char *)sysInfo.OsVer.szCSDVersion);
		printf("%s\n", sysInfo.szComputerName);
		printf("%s\n", sysInfo.szUserName);
		::send(sock, (const char *)&sysInfo, sizeof(SYS_INFO), 0);
		bRet = TRUE;
	}
	//打开光驱
	else if(!strcmp(szCmd, "open"))
	{
		//
		SetCdaudio(TRUE);
		bRet = TRUE;
	}
	//关闭光驱
	else if(!strcmp(szCmd, "close"))
	{
		//
		SetCdaudio(FALSE);
		bRet = TRUE;
	}
	//交换鼠标左右键功能
	else if(!strcmp(szCmd, "swap"))
	{
		//
		SetMouseButton(TRUE);
		bRet = TRUE;
	}
	//回复鼠标左右键功能
	else if(!strcmp(szCmd, "restore"))
	{
		//
		SetMouseButton(FALSE);
		bRet = TRUE;
	}
	else
	{
		//
		::send(sock, "no this commend!", 
			strlen("no this commend!") + sizeof(char),0);
	}
	return bRet;
}


//获得系统信息
void GetSysInfo(SYS_INFO * sysInfo)
{
	unsigned long nSize = MAXBYTE;
	sysInfo->OsVer.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
	//获得操作系统版本信息
	::GetVersionEx(&sysInfo->OsVer);
	//获得计算机名称
	::GetComputerNameA(sysInfo->szComputerName, &nSize);
	
	//获得当前登录名称
	nSize = MAXBYTE;
	::GetUserNameA(sysInfo->szUserName, &nSize);
	
}

void SetCdaudio(BOOL bOpen)
{
	if(bOpen)
	{
		//打来光驱
		::mciSendStringA("set cdaudio door open", NULL, NULL, NULL);
	}
	else
	{
		//关闭光驱
		::mciSendStringA("set cdautio door closed", NULL, NULL, NULL);
	}
}

void SetMouseButton(BOOL bSwap)
{
	if(bSwap)
	{
		//交换左右键
		::SwapMouseButton(TRUE);
	}
	else
	{
		//恢复
		::SwapMouseButton(FALSE);
	}
}

 
 
客户端:
//#include <Windows.h>
#include <WinSock2.h>
#include <stdio.h>
#include <conio.h>

#pragma comment (lib, "ws2_32")

#define NAME_LEN 20

typedef struct _SYS_INFO
{
	OSVERSIONINFO OsVer;
	char szComputerName[NAME_LEN];
	char szUserName[NAME_LEN];
} SYS_INFO, *PSYS_INFO;

void ShowSysInfo(PSYS_INFO sysInfo)
{
	if(sysInfo->OsVer.dwPlatformId == VER_PLATFORM_WIN32_NT)	//平台ID
	{
		if(sysInfo->OsVer.dwMajorVersion == 6 && sysInfo->OsVer.dwMinorVersion ==1)
		{
			printf("windows 7 %s\n", sysInfo->OsVer.szCSDVersion); // 系统和补丁包
		}
		else
		{
			printf("other system\n");
		}
	}
	printf("computer name is: %s \n", sysInfo->szComputerName);
	printf("user name is: %s \n", sysInfo->szUserName);
}

int main()
{
	WSADATA wsaData;
	WSAStartup(MAKEWORD(2, 2), &wsaData);

	SOCKET clientSock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
	//服务器端信息
	sockaddr_in serverAddr;
	serverAddr.sin_family = PF_INET;
	serverAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
	serverAddr.sin_port = htons(8008);

	//连接服务器端
	if(connect(clientSock, (SOCKADDR*)&serverAddr, sizeof(SOCKADDR)) == -1)
	{
		printf("连接失败!");
	}

	printf("客户端已启动...\n");

	while(TRUE)
	{
		char buff[MAXBYTE] = {0};
		char cmd[MAXBYTE] = {0};
		//接收信息
		recv(clientSock, buff, MAXBYTE, 0);
		printf("%s", buff);
		//输入命令
		scanf("%s", cmd);
		//发送命令
		send(clientSock, cmd, MAXBYTE, 0);
		if( !strcmp(cmd, "exit"))
		{
			printf("login out! \r\n");
			break;
		}
		memset(buff, 0, MAXBYTE);
		recv(clientSock, buff, MAXBYTE, 0);
		if( !strcmp(cmd, "getsysinfo"))
		{
			PSYS_INFO sysInfo = (PSYS_INFO)buff;
			ShowSysInfo(sysInfo);
		}
		else 
		{
			printf("%s \r\n", buff);
		}
	}
	printf("you have exited!\n");
	getch();
	closesocket(clientSock);
	WSACleanup();
	return 0;
}
 
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值