winsocket<一> 套接字基础

最近在学习winsocket整理一下:

IP与端口:

1、网络中有很多的主机,怎么区分主机?

             用IP来标识不同的主机,其中现在主要用的是IPV4(32位),随着发展,IPV4无法满足连入的主机数量——地址不够用,所以以后应用更强大的IPV6(128为)。

 2、同一台主机中有很多的服务,如何区分不同的服务?

            用端口号来区分不同的服务,端口号是一个整数,范围是:0 ~ 65535;对应于TCP和UDP有相应的TCP端口和UDP端口

            其中:0-1023为通用端口,这些端口已经绑定了某些服务;

                      1024-49151 为已注册端口号,供一般程序使用,我们开发winsocket程序时使用这个范围内的端口;

      49152-65535为动态或私有端口


在winsocket中套接字SOCKET的定义:

typedef unsigned int u_int;

typedef u_int SOCKET;

从上面的定义我们可以得知其实,SOCKET就是一个无符号的整数,并且INVALID_SOCKET是唯一一个无效的套接字,其他所有的 0 - INVALID_SOCKET-1都是有效的(INVALID_SOCKET = 4294967295,这是我直接把INVALID_SOCKET打印出来的结果);由于INVALID_SOCKET是一个无效的套接字,所以我们可以利用这个值来判断我们创建的套接字是否有效。

INVALID_SOCKET的申明:#define INVALID_SOCKET (SOCKET)(~0)


一、TCP套接字基础

基本的模式:

     Server端:创建socket->绑定地址->设置为监听->接受链接->交互数据(收发数据)->关闭

     Client端:创建socket->连接服务器->交互数据(收发数据)->关闭


<span style="font-size:14px;">//Server端
#include<iostream>
#include <WINSOCK2.H>
#pragma comment(lib, "ws2_32.lib")
using namespace std;

int main()
{
	//<1>创建Socket
	WORD wVersionRequested;//版本
	WSADATA wsaData;//
	int nErrorCode;//错误代码
	wVersionRequested = MAKEWORD(2, 2);//生成版本
	nErrorCode = WSAStartup(wVersionRequested, &wsaData);
	
	if (nErrorCode != 0)
	{//winsocket异步套接字启动失败情况
		cout << "WinSocket fail startup!" << endl;
		return 1;
	}

	//check version
	if (LOBYTE(wsaData.wVersion)!=2 || HIBYTE(wsaData.wVersion)!=2)
	{
		WSACleanup();//delete data
		return 1;
	}

	SOCKET sockServer;
	sockServer = socket(AF_INET, SOCK_STREAM, 0);

	//<2>绑定地址
	SOCKADDR_IN addrServer;
	addrServer.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
	addrServer.sin_family = AF_INET;
	addrServer.sin_port = htons(8888);
	bind(sockServer, (SOCKADDR *)&addrServer, sizeof(SOCKADDR));

	//<3>打开监听
	listen(sockServer, 5);

	SOCKADDR_IN addrClient;
	int nLen = sizeof(SOCKADDR);
	cout << "here is Server" << endl;
	while (true)
	{
		//<4>接受链接
		SOCKET sockConn = accept(sockServer, (SOCKADDR *)&addrClient, &nLen);
		char sendBuf[1024] = {0};
		
		sprintf_s(sendBuf, sizeof(sendBuf), "Welcome %s to here!\nwhat can I help you?");
		send(sockConn, sendBuf, strlen(sendBuf)+1, 0);
		char recvBuf[1024] = {0};
		//<5>数据交互
		while (true)
		{
			//收数据
			recv(sockConn, recvBuf, sizeof(recvBuf) - 1, 0);
			cout << "Client: " << recvBuf << endl;
			if (recvBuf[0] == 'n'){ break; }
			cout << "Server: ";
			cin >> sendBuf;
			//发数据
			send(sockConn, sendBuf, strlen(sendBuf)+1, 0);
		}
		//<6>关闭socket
		closesocket(sockConn);
	}

	system("pause");
	return 0;
}</span>

<span style="font-size:14px;">//Client端
#include<iostream>
#include<WINSOCK2.H>
#pragma comment(lib, "ws2_32.lib")

using namespace std;

int main()
{
	//<1>创建socket
	WORD wVersion;
	WSADATA wsaData;
	int nErrorCode;
	wVersion = MAKEWORD(2, 2);
	nErrorCode = WSAStartup(wVersion, &wsaData);
	if (nErrorCode != 0)
	{
		cout << "WinSocket fail startup !" << endl;
		return 1;
	}

	if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2)
	{
		WSACleanup();
		return 1;
	}

	SOCKET sockClient = socket(AF_INET, SOCK_STREAM, 0);

	SOCKADDR_IN addrServer;
	addrServer.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
	addrServer.sin_family = AF_INET;
	addrServer.sin_port = htons(8888);

	//<2>链接服务器
	connect(sockClient, (SOCKADDR *)&addrServer, sizeof(SOCKADDR));

	char sendBuf[1024] = { 0 };
	char recvBuf[1024] = { 0 };

	cout << "here is Client !" << endl;
	//<3>数据交互
	while (true)
	{
		//收
		recv(sockClient, recvBuf, sizeof(recvBuf) - 1, 0);
		cout << "Server: " << recvBuf << endl;
		if (recvBuf[0] == 0)
		{
			break;
		}
		cout << "Client: ";
		cin >> sendBuf;
		//发
		send(sockClient, sendBuf, strlen(sendBuf) + 1, 0);
	}

	//<4>关闭socket
	closesocket(sockClient);
	WSACleanup();
	system("pause");
	return 0;
}</span>


二、UDP套接字基础

server端:创建socket->绑定地址->数据交互->关闭

Client端:创建socket->数据交互->关闭



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值