C++socket网络编程

1.描述:使用socket编程完成数据传输

1.1 TCP / IP三次握手

1客户端向服务器发送信息SYN J
2.服务器接受到之后 向客户端发送 ack J+1 来告诉客户端服务器能接收到正确的信息 同时发送SYN K给客户端
3.客户端返回ack K+1 给服务器来告诉服务器 它能接收到正确的信息

三次握手

1.2 客户端 服务器端 流程图

流程图

2.服务端代码实现

手动添加 ws2_32.lib库
在这里插入图片描述

#include <iostream>
#include <Windows.h>
#include <string>
#include <WinSock.h>
using namespace std;
int main(int argc , char* argv[])
{
	//初始化WSA
	WSADATA ws;
	WSAStartup(MAKEWORD(2,2), &ws);
	//创建socket
	SOCKET sock = socket(AF_INET, SOCK_STREAM,IPPROTO_TCP);//AF_INET->tcp/ip 协议,SOCK_STREAM ->tcp协议
	if (sock == INVALID_SOCKET)
	{
		cout<<"create socket failed!"<<endl;
	}
	else
	{
		cout<<sock<<endl;
	}

	sockaddr_in saddr;
	saddr.sin_family = AF_INET;
	saddr.sin_port = htons(99999);//本地字节序 -> 网络字节序  
	saddr.sin_addr.S_un.S_addr = INADDR_ANY;//绑定ip地址,0表示任意ip地址都可以访问
	
	if(bind(sock, (LPSOCKADDR)&saddr, sizeof(saddr)) == SOCKET_ERROR)
	{
		cout<<"bind port failed!"<<endl;
	}
	else
	{
		cout<<"bind port success!"<<endl;

	}
	/*
	面向连接的服务器 使用它将一个套接字置为被动模式,并准备接收传入链接,用于服务器,指明某个套接字连接是被动的
	*/
	//开始监听
	if(listen(sock,10) == SOCKET_ERROR)//第一个参数:指明创建连接的套接字,第二个参数:该套接字使用的队列长度,指定在请求队列中允许的最大请求数
	{
		cout<<"listen error!"<<endl;
	}
	else
	{
		cout<<"listen success!"<<endl;
	}
	//循环接收数据
	sockaddr_in caddr;
	int caddrLen = sizeof(caddr);
	char revData[1024]={0};
	while (true)
	{
		cout<<"等待连接..."<<endl;
		/*
		功能:获取传入连接的请求,返回新的连接的套接字描述符
		为每个新的连接请求创建一个新的套接字,服务器值对新的连接使用该套接字,原来的监听套接字接受其它连接请求
		新的连接上传输数据使用新的套接字,使用完毕,服务器将关闭这个套接字
		参数:第一个参数:指明正在监听的套接字
			  第二个参数:提出连接请求的主机地址
			  第三个参数:地址长度
		*/
		SOCKET newSock = accept(sock, (sockaddr*)&caddr,&caddrLen);//sock只用于连接,连接成功之后accept会生成一个新的sock用于通信
		if (newSock == INVALID_SOCKET)
		{
			cout<<"accept error!"<<endl;
			continue;
		}
		else
		{
			cout<<"有新的连接:"<<inet_ntoa(caddr.sin_addr)<<endl;
			//接收数据
			while (1)
			{
				int recvLen = recv(newSock, revData,sizeof(revData)-1,0);
				if (recvLen <= 0)break;
				if (strstr(revData,"quit") != NULL)
				{
					cout<<"对方已断开连接.."<<endl;
					break;
				}
				cout<<"message from client:"<<revData<<endl;
				//发送数据
				string data;
				cin>>data;
				if (data == "quit")
				{
					cout<<"结束会话!"<<endl;
					break;
				}
				const char* sendData;
				sendData = data.c_str();//string ->const char*
				send(newSock, sendData , strlen(sendData),0);//发送数据
			}
			closesocket(newSock);
			break;
		}
	}
	closesocket(sock);
	WSACleanup();
	system("pause");
	return 0;
}


3.客户端代码实现

#include <WinSock.h>
#include <iostream>
#include <string>
#include <Windows.h>
using namespace std;
int main(int argc, char* argv[])
{
	WSADATA ws;
	WSAStartup(MAKEWORD(2,2), &ws);
	//创建socket
	SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (sock == INVALID_SOCKET)
	{
		cout<<"create socket failed!"<<endl;
	}
	else
	{
		cout<<sock<<"create success!"<<endl;
	}
	sockaddr_in caddr;
	caddr.sin_family = AF_INET;
	caddr.sin_port = htons(99999);
	caddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
	if (connect(sock,(sockaddr*)&caddr, sizeof(caddr)) == SOCKET_ERROR)
	{
		cout<<"connect failed !"<<endl;
		closesocket(sock);
	}
	else
	{
		cout<<"connect success !"<<endl;
		while (1)
		{
			string data;
			cin>>data;
			if (data == "quit")
			{
				cout<<"结束会话!"<<endl;
				break;
			}
			const char* sendData;
			sendData = data.c_str();//string ->const char*
			send(sock, sendData, strlen(sendData),0);
			char recvData[1024]={0};
			int recLen = recv(sock, recvData,sizeof(recvData)-1, 0);
			if (strstr(recvData,"quit") != NULL)
			{
				cout<<"对方已断开连接.."<<endl;
				break;
			}
			if (recLen > 0)
			{
				cout<<"message from server:"<<recvData<<endl;
			}
		}
		closesocket(sock);
	}
	WSACleanup();
	system("pause");
	return 0;
}

4.实现效果

服务端效果图
客户端效果图

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值