Socket编程的TCP、UDP相关例子

Socket编程相关例子

转载自:https://blog.csdn.net/xiaoquantouer/article/details/58001960

TCP:

服务器端:

#include "stdafx.h"
#include <iostream>
#include <WinSock2.h>
#include <WS2tcpip.h>  //inet_ntop函数使用所要加的头文件
using namespace std;
#pragma comment(lib, "Ws2_32.lib")
#pragma warning(disable:4996);


int main()
{
	//初始化socket库
	WSADATA wsaData;
	if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) //请求2.2版本的WinSock库,成功则返回0
	{
		return 0;  //失败则退出
	}
	
	//检测请求版本号是否正确,通常可以不加
	if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2)
	{
		WSACleanup(); //不正确则清除信息
		return 0;
	}

	//创建监听套接字
	SOCKET slisten = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (slisten == INVALID_SOCKET)
	{
		cout << "socket error!" << endl;
		return 0;
	}

	sockaddr_in sin;
	sin.sin_family = AF_INET;
	sin.sin_port = htons(8888);
	sin.sin_addr.S_un.S_addr = INADDR_ANY;
	//sin.sin_addr.S_un.S_addr = inet_addr("172.16.2.6");
	if (bind(slisten, (const sockaddr*)&sin, sizeof(sin)) == SOCKET_ERROR)
	{
		cout << "bind error!" << endl;
	}
	
	if (listen(slisten, SOMAXCONN) ==SOCKET_ERROR)
	{
		cout << "listen error!" << endl;
	}

	SOCKET sClient;
	sockaddr_in remoteAddr;
	int nAddrlen = sizeof(remoteAddr);
	char revData[255];
	cout << "等待链接..." << endl;
	while (true)
	{
		sClient = accept(slisten, (sockaddr*)&remoteAddr, &nAddrlen);
		if (sClient == INVALID_SOCKET)
		{
			cout << "accept error!" << endl;
			continue; 
		}
		char str[INET_ADDRSTRLEN];
		inet_ntop(AF_INET, &remoteAddr.sin_addr, str, sizeof(str));
		cout << "接收到一个连接地址:" << str << endl;
		//int n = 4;
		while (true)
		{
			int ret = recv(sClient, revData, 255, 0);
			if (ret > 0)
			{
				revData[ret] = 0x00;
				cout << revData << endl;
			}
			else if (ret == SOCKET_ERROR)
			{
				cout << "当前连接关闭!" << endl;
				break;
			}

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

客户端:

#include "stdafx.h"
#include <WinSock2.h>
#include <windows.h>
#include <iostream>
#include <WS2tcpip.h>
#include <string>
using namespace std;
#pragma comment(lib,"ws2_32.lib")
#pragma warning(disable:4996);

int main()
{
	WSADATA data;
	if (WSAStartup(MAKEWORD(2, 2), &data) != 0)
	{
		cout << "WSAStartup error!" << endl;
		return 0;
	}

	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, (const sockaddr*)&serAddr, sizeof(serAddr)) == SOCKET_ERROR)
	{
		//连接失败
		cout << "connect error!" << endl;
		closesocket(sclient);
		return 0;
	}
	else
	{
		cout << "connect success!" << endl;
	}

	while (true)
	{
		//连接成功后发送信息
		string data;
		cin >> data;
		const char* sendData;
		sendData = data.c_str();
		if (send(sclient, sendData, strlen(sendData), 0)==SOCKET_ERROR)
		{
			cout << "send error!" << endl;
			cout << WSAGetLastError() << endl;
		}

		//接收信息
		char recvData[255];
		int ret = recv(sclient, recvData, 255, 0);
		if (ret > 0)
		{
			recvData[ret] = 0x00;
			cout << recvData << endl;
		}	
	}
	closesocket(sclient);
	WSACleanup();
	return 0;
}

UDP:

服务器端:

#include "stdafx.h"
#include <iostream>
#include <WinSock2.h>
#include <WS2tcpip.h>  //inet_ntop函数使用所要加的头文件
using namespace std;
#pragma comment(lib, "Ws2_32.lib")
#pragma warning(disable:4996);


int main()
{
	//初始化socket库
	WSADATA wsaData;
	if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) //请求2.2版本的WinSock库,成功则返回0
	{
		return 0;  //失败则退出
	}
	
	//检测请求版本号是否正确,通常可以不加
	if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2)
	{
		WSACleanup(); //不正确则清除信息
		return 0;
	}

	//创建监听套接字
	SOCKET serSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
	if (serSocket == INVALID_SOCKET)
	{
		cout << "socket error!" << endl;
		return 0;
	}

	sockaddr_in serAddr;
	serAddr.sin_family = AF_INET;
	serAddr.sin_port = htons(8888);
	serAddr.sin_addr.S_un.S_addr = INADDR_ANY;
	//sin.sin_addr.S_un.S_addr = inet_addr("172.16.2.6");
	if (bind(serSocket, (const sockaddr*)&serAddr, sizeof(serAddr)) == SOCKET_ERROR)
	{
		cout << "bind error!" << endl;
		closesocket(serSocket);
		return 0;
	}
	
	sockaddr_in remoteAddr;
	int nAddrlen = sizeof(remoteAddr);
	while (true)
	{
		char recvData[255];
		cout << "等待连接....." << endl;
		int ret = recvfrom(serSocket, recvData, strlen(recvData), 0, (sockaddr*)&remoteAddr, &nAddrlen);
		if (ret > 0)
		{
			recvData[ret] = 0x00;
			printf("接受到一个连接:%s\r\n", inet_ntoa(remoteAddr.sin_addr));
			printf(recvData);
		}
		const char* sendData = "一个来自服务端的UDP数据包\n";
		sendto(serSocket, sendData, strlen(sendData), 0, (sockaddr*)&remoteAddr, nAddrlen);
	}
	closesocket(serSocket);
	WSACleanup();
	return 0;
}

客户端:

#include "stdafx.h"
#include <WinSock2.h>
#include <windows.h>
#include <iostream>
#include <WS2tcpip.h>
#include <string>
using namespace std;
#pragma comment(lib,"ws2_32.lib")
#pragma warning(disable:4996);

int main()
{
	WSADATA data;
	if (WSAStartup(MAKEWORD(2, 2), &data) != 0)
	{
		cout << "WSAStartup error!" << endl;
		return 0;
	}

	SOCKET sclient = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
	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");
	int len = sizeof(serAddr);

	const char* sendData = "来自客户端的数据包.\n";
	sendto(sclient, sendData, strlen(sendData), 0, (sockaddr*)&serAddr, len);

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

	closesocket(sclient);
	WSACleanup();
	return 0;
}

Windows下的socket程序和Linux区别:

(1) Windows下的socket程序依赖Winsock.dll或ws2_32.dll,必须提前加载。DLL有两种加载方式。

(2) Linux使用“文件描述符”的概念,而Windows使用“文件句柄”的概念;Linux不区分socket文件和普通文件,而Windows区分;Linux下socket()函数的返回值为int类型,而Windows下为SOCKET类型,也就是句柄。

(3) Linux下使用read()/write()函数读写,而Windows下使用recv()/send()函数发送和接收

(4) 关闭socket时,Linux使用close()函数,而Windows使用closesocket()函数。
 

猜你喜欢

转载自blog.csdn.net/SwordArcher/article/details/83055516