Win32TCP

常见的网络编程

分为七层网络架构:应用层、表示层、会话层、传输层、网络层、数据连接层、物理层
五层网络结构:应用层、传输层、网络层、数据连接层、物理层

socket 套接字(IP地址、端口号)
tcp/ip 协议簇

ipv4 (32位) ipv6(64位)

ip地址分类:

A类: 0 网络号(7位) 主机号(24位)
B类: 10 网络号(14位) 主机号(16位)
C类: 110 网络号(21位) 主机号(8位)

tcp 通信模型

一、三次握手
服务器和客户端需要建立一种稳定的传输管道,需要3个步骤
1、由客户端向服务器端发送信息,发一个报文(message syn)
2、服务器把刚刚接收到的客户端的报文重新发回去,再发一个报文(ack)
3、客户端在向服务器端发送报文(ack)

二、四次挥手
断开稳定的传输通需要四个步骤
1、客户端向服务器端,发送fin(结束标记)
2、服务器收到fin,它会发回一个ack
3、服务器关闭客户端的链接
4、客户端发回ack确认

TCP模型

C(客户端)/S(服务器)模型 一对一的关系
1、准备工作
2、确认版本信息 ,要确认socket的版本 ipv4
3、创建套接字 (socket)
4、初始化协议地址
5、绑定(s)
6、监听(s)
7、接收连接(s) 客户端需要连接服务器©
8、连接完成,开始通信
9、关闭socket

接收

#include "stdafx.h"
//1、准备工作
#include< Winsock2.h>
#pragma comment(lib,"Ws2_32.lib")

void color(const unsigned short color1)
{
	if (color1 >= 0 && color1 <= 15)
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), color1);
	else
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 7);
}
int _tmain(int argc, _TCHAR* argv[])
{
	color(15);
	//2、确认版本信息
	WSADATA wsaData;
	WSAStartup(MAKEWORD(2, 2), &wsaData);
	if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2){
		printf("请求版本失败,启动不成功\n");
		return -1;
	}
	printf("请求版本成功\n");

	//3、创建套接字 (socket)
	/*第一个参数协议:协议决定了socket的地址类型,在通信中必须采用对应的协议
	AF_INET,决定了用ipv4地址(32位)与端口号(16位)的组合
	第二个参数是类型,SOCK_STREAM(流式)
	//第三个参数是决定用tcp还是udp的传输协议    IPPROTO_TCP代表TCP
	*/
	SOCKET serverSocket=socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (INVALID_SOCKET == serverSocket){
		printf("创建套接字失败\n");
		WSACleanup();
		return -1; 
	}
	printf("创建套接字成功\n");

	//4、初始化协议地址
	SOCKADDR_IN serverAddr = {};
	//指定协议簇,需要和第三部的第一个参数一致
	serverAddr.sin_family = AF_INET;
	//指定端口号
	serverAddr.sin_port = htons(8080);
	//指定ip地址
	/*inet_addr()是将一个点分十进制的ip地址转换成一个长整数类型*/
	serverAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
	//INADDR_ANY 表示不确定地址  任意地址只要能找到端口号就能用
	//serverAddr.sin_addr.S_un.S_addr = INADDR_ANY;

	//5、绑定(s)
	int s=bind(serverSocket, (sockaddr*)&serverAddr, sizeof(serverAddr));
	if (s == SOCKET_ERROR){
		printf("绑定失败\n");
		closesocket(serverSocket);
		WSACleanup();
		return -1;
	}
	printf("绑定成功\n");

	//6、监听(s)
	//listen(serverSocket, 10);
	if (SOCKET_ERROR ==listen(serverSocket, 10))
	{
		printf("监听失败\n");
		closesocket(serverSocket);
		WSACleanup();
		return -1;
	}

	printf("监听成功\n");

	//7、接收连接(s)
	SOCKADDR_IN clientAddr = {};
	int len = sizeof(clientAddr);
    SOCKET clientSocket=accept(serverSocket, (sockaddr*)(&clientAddr), &len);
	if (clientSocket == INVALID_SOCKET)
	{
		printf("连接失败\n");
		closesocket(serverSocket);
		WSACleanup();
		return -1;
	}
	printf("连接成功,客户端的ip:  %s\n请等待...\n\n", inet_ntoa(clientAddr.sin_addr));
	//8、连接完成,开始通信
	char buff[128] = {};
	int bufflen = 0;

	char clientBuff[128] = {};
	while (1)
	{
		memset(buff, 0, sizeof(buff));
		bufflen=recv(clientSocket, buff, sizeof(buff)-1, 0);
		color(6); 
		if (bufflen > 0){
			printf("接收的内容:        %s\n", buff);
		}

		memset(clientBuff, 0, sizeof(clientBuff));
		color(15);
		printf("请输入:            ");
		scanf_s("%s", clientBuff, sizeof(clientBuff)-1);
		bufflen = send(clientSocket, clientBuff, sizeof(clientBuff)-1, 0);
		if (bufflen > 0){
			printf("发送成功,请等待...\n");
		}

	}
		//9、关闭socket
	closesocket(clientSocket);
	closesocket(serverSocket);
	WSACleanup();
	return 0;
}

发送

#include "stdafx.h"
#include <stdio.h>
//1、准备工作
#include< Winsock2.h>
#pragma comment(lib,"Ws2_32.lib")

void color(const unsigned short color1)
{
	if (color1 >= 0 && color1 <= 15)
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), color1);
	else
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 7);
}

int _tmain(int argc, _TCHAR* argv[])
{
	color(15);
	//2、确认版本信息
	WSADATA wsaData;
	WSAStartup(MAKEWORD(2, 2), &wsaData);
	if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2){
		printf("请求版本失败,启动不成功\n");
		return -1;
	}
	printf("请求版本成功\n");

	//3、创建套接字 (socket)
	/*第一个参数协议:协议决定了socket的地址类型,在通信中必须采用对应的协议
	AF_INET,决定了用ipv4地址(32位)与端口号(16位)的组合
	第二个参数是类型,SOCK_STREAM(流式)
	//第三个参数是决定用tcp还是udp的传输协议    IPPROTO_TCP代表TCP
	*/
	SOCKET clientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (INVALID_SOCKET == clientSocket){
		printf("创建套接字失败\n");
		WSACleanup();
		return -1;
	}
	printf("创建套接字成功\n");

	//4、初始化协议地址
	SOCKADDR_IN clientAddr = {0};
	//指定协议簇,需要和第三部的第一个参数一致
	clientAddr.sin_family = AF_INET;
	//指定端口号
	int b;
	printf("输入端口号:");
	scanf("%d", &b);
	clientAddr.sin_port = htons(b);
	//指定ip地址
	/*inet_addr()是将一个点分十进制的ip地址转换成一个长整数类型112.74.89.58 :35063*/
	char a[20];
	printf("输入地址:");
	scanf("%s", a);
	clientAddr.sin_addr.S_un.S_addr = inet_addr(a);
	//INADDR_ANY 表示不确定地址  任意地址只要能找到端口号就能用
	//clientAddr.sin_addr.S_un.S_addr = INADDR_ANY;

	//5、客户端需要连接服务器(c)

	if (SOCKET_ERROR == connect(clientSocket, (sockaddr *)&clientAddr, sizeof(clientAddr)))
	{
		printf("连接失败\n");
		WSACleanup();
		closesocket(clientSocket);
		return -1;
	}
	printf("连接成功\n\n\n");
	//6、连接完成,开始通信
	char buff[128] = {};
	int bufflen = 0;
	char clientBuff[128] = {};
	while (1)
	{
		memset(buff, 0, sizeof(buff));
		color(15);
		printf("请输入:            ");
		scanf_s("%s", buff, sizeof(buff)-1);
		bufflen = send(clientSocket, buff, sizeof(buff)-1, 0);
		if (bufflen > 0){
			printf("发送成功,请等待...\n");
		}

		memset(clientBuff, 0, sizeof(clientBuff));
		bufflen = recv(clientSocket, clientBuff, sizeof(clientBuff)-1, 0);
		color(6);
		if (bufflen > 0){
			printf("接收的内容:        %s\n", clientBuff);
		}
	}
	
	//7、关闭socket
	closesocket(clientSocket);
	WSACleanup();
	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值