欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

C++ socket网络编程

程序员文章站 2022-04-08 22:50:14
...



1. 参考文献

2. TCP通信

@服务器端

// server.cpp : 定义控制台应用程序的入口点。
//
//TCP服务器端程序

#include "stdafx.h"
#include <iostream>
#include <WinSock2.h> //windows socket header file

#pragma comment(lib,"ws2_32.lib") //静态加入一个lib文件,也就是库文件ws2_32.lib,提供了对以下网络相关API的支持,否则需要动态载入ws2_32.dll
using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
	//初始化WSA  
	WORD sockVersion = MAKEWORD(2, 2); //MAKEWORD 宏返回一个word大小的内存 高位是2 低位也是2 所以版本是2.2
	WSADATA wsaData; //数据结构,用来存储被WSAStartup函数调用后返回的Windows Sockets数据
	//WSA:Windows Sockets Asynchronous,Windows异步套接字的启动命令.WSAStartup必须是应用程序或DLL调用的第一个Windows Sockets函数
	if (WSAStartup(sockVersion, &wsaData) != 0)
	{
		return 0;
	}

	//创建套接字  
	SOCKET slisten = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); //sock_stream:字节流传输
	if (slisten == INVALID_SOCKET) //invalid socket:无效的套接字
	{
		cout << "create socket error !" << endl;
		return 0;
	}

	//绑定IP和端口  
	sockaddr_in sin; //IPv4 Socket address, internet style
	sin.sin_family = AF_INET; //sin_family表示协议族,af_inet表示tcp/ip协议
	sin.sin_port = htons(8888); //sin_port表示端口号
	sin.sin_addr.S_un.S_addr = INADDR_ANY; //sin_addr表示联合体,可以用多种方式表示ip地址,一般我们使用其中的最后一种方式,
	//即用无符号长整型数据来表示IP地址。此时,用的是s_nu数据成员,s_un是一个结构体,
	//其中只有一个数据成员,即s_addr。
	//INADDR_ANY就是指定地址为0.0.0.0的地址,这个地址事实上表示不确定地址,或“所有地址”、“任意地址”。
	//绑定套接字到一个IP地址和一个端口上(bind()),slisten:套接字,sin:IPv4 Socket address and internet style
	if (bind(slisten, (LPSOCKADDR)&sin, sizeof(sin)) == SOCKET_ERROR)
	{
		cout << "bind error !" << endl;
	}

	//开始监听  
	if (listen(slisten, 5) == SOCKET_ERROR)//5:后备日志当前被(默认地)限制为5
	{
		cout << "listen error !" << endl;
		return 0;
	}

	//循环接收数据  
	SOCKET sClient;
	sockaddr_in remoteAddr;
	int nAddrlen = sizeof(remoteAddr);
	char revData[255];
	while (true)
	{
		cout << "阻塞。。。。等待连接。。。" << endl;
		//请求到来后,接受连接请求,返回一个新的对应于此次连接的套接字(accept())
		sClient = accept(slisten, (SOCKADDR *)&remoteAddr, &nAddrlen);
		if (sClient == INVALID_SOCKET)//无效套接字
		{
			cout << "accept error !" << endl;
			continue;
		}
		//将一个32位网络字节序的二进制IP地址转换成相应的点分十进制的IP地址
		cout << "接受到一个连接:" << inet_ntoa(remoteAddr.sin_addr) << endl;

		//接收数据  
		int ret = recv(sClient, revData, 255, 0);
		if (ret > 0)
		{
			revData[ret] = 0x00;
			//printf(revData);
			cout << revData << endl;
			//cout << endl;
		}

		//发送数据  
		const char * sendData = "你好,TCP客户端!\n";
		send(sClient, sendData, strlen(sendData), 0);
		closesocket(sClient);
	}

	closesocket(slisten);//关闭加载的套接字
	WSACleanup();


	return 0;
}

@客户端

// client.cpp : 定义控制台应用程序的入口点。
//
//TCP客户端程序

#include "stdafx.h"
#include<winsock2.h>
#include<iostream>
#include<string>

using namespace std;
#pragma comment(lib, "ws2_32.lib")

int _tmain(int argc, _TCHAR* argv[])
{
	WORD sockVersion = MAKEWORD(2, 2);
	WSADATA data;
	if (WSAStartup(sockVersion, &data) != 0)
	{
		return 0;
	}
	//加载套接字库,创建套接字(WSAStartup()/socket())
	while (true)
	{
		SOCKET sclient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
		if (sclient == INVALID_SOCKET)
		{
			cout << "invalid socket!" << endl;
			return 0;
		}

		sockaddr_in serAddr;
		serAddr.sin_family = AF_INET;
		serAddr.sin_port = htons(8888);
		serAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
		if (connect(sclient, (sockaddr *)&serAddr, sizeof(serAddr)) == SOCKET_ERROR)
		{
			//连接失败 
			cout << "connect error !" << endl;
			closesocket(sclient);
			return 0;
		}

		string data;
		cin >> data;
		const char * sendData;
		sendData = data.c_str();   //string转const char* 

		/*
		send()用来将数据由指定的socket传给对方主机
		int send(int s, const void * msg, int len, unsigned int flags)
		s为已建立好连接的socket,msg指向数据内容,len则为数据长度,参数flags一般设0
		成功则返回实际传送出去的字符数,失败返回-1,错误原因存于error
		*/
		send(sclient, sendData, strlen(sendData), 0);

		char recData[255];
		int ret = recv(sclient, recData, 255, 0);
		if (ret>0)
		{
			recData[ret] = 0x00;
			cout << recData << endl;
		}
		closesocket(sclient);
	}

	WSACleanup();

	system("pause");

	return 0;
}

3. UDP通信

@服务器端

// UDP_client.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <iostream>
#include <WinSock2.h>

#pragma comment(lib,"ws2_32.lib")
using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
	//启动WSA
	WORD sockVersion = MAKEWORD(2, 2);
	WSADATA wsaData;
	if (WSAStartup(sockVersion, &wsaData) != 0)
	{
		return 0;
	}
	//创建套接字
	SOCKET serSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
	if (serSocket == INVALID_SOCKET)
	{
		cout << "Server socket has error!" << endl;
		return 0;
	}
	//绑定IP和端口
	sockaddr_in serAddr;
	serAddr.sin_family = AF_INET; //协议族,af_inet表示tcp/udp协议
	serAddr.sin_port = htons(8888); //端口号
	serAddr.sin_addr.S_un.S_addr = INADDR_ANY;//INADDR_ANY指定地址为0.0.0.0,这个地址表示不确定地址,或者“所有地址”
	if (bind(serSocket, (sockaddr*)&serAddr, sizeof(serAddr)) == SOCKET_ERROR)
	{
		cout << "Bind error!" << endl;
		closesocket(serSocket);
		return 0;
	}
	//循环接受数据
	sockaddr_in remoteAddr;
	int nAddrLen = sizeof(remoteAddr);
	while (true)
	{
		char revData[255];
		int ret = recvfrom(serSocket, revData, 255, 0, (sockaddr*)&remoteAddr, &nAddrLen);
		if (ret > 0)
		{
			revData[ret] = 0x00;
			cout << "接受到一个连接:" << inet_ntoa(remoteAddr.sin_addr) << "\r\n";
			cout << revData << endl;
		}
		const char * sendData = "一个来自服务端的UDP数据包\n";
		sendto(serSocket, sendData, strlen(sendData), 0, (sockaddr *)&remoteAddr, nAddrLen);
	}

	closesocket(serSocket);
	WSACleanup();

	system("pause");
	return 0;
}

@客户端

// UDP_server.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <WinSock2.h>
#include <iostream>
#include <string>

#pragma comment(lib,"ws2_32.lib")
using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
	//加载套接字
	WSADATA serWsaData;
	WORD sockVersion = MAKEWORD(2, 2);
	if (WSAStartup(sockVersion, &serWsaData) != 0)
	{
		cout << "Startup error!" << endl;
		return 0;
	}

	SOCKET sclient = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);

	sockaddr_in sin;
	sin.sin_family = AF_INET;
	sin.sin_port = htons(8888);
	sin.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
	int len = sizeof(sin);

	string data;
	cin >> data;
	const char * sendData;
	sendData = data.c_str();   //string转const char* 
	//const char * sendData = "来自客户端的数据包.\n";
	sendto(sclient, sendData, strlen(sendData), 0, (sockaddr*)&sin, len);

	char recvData[255];
	int ret = recvfrom(sclient, recvData, 255, 0, (sockaddr *)&sin, &len);
	if (ret > 0)
	{
		recvData[ret] = 0x00;
		printf(recvData);
	}

	closesocket(sclient);
	WSACleanup();

	system("pause");
	return 0;
}
相关标签: socket编程