zoukankan      html  css  js  c++  java
  • C++tcp服务器和跨平台客户端

    TcpServer

    #define WIN32_LEAN_AND_MEAN
    #define _WINSOCK_DEPRECATED_NO_WARNINGS
    #include <windows.h>
    #include <winsock2.h>
    #include <iostream>
    #include <thread>
    #include <mutex>
    #include <chrono>
    #pragma comment(lib,"ws2_32.lib")
    
    std::mutex g_Mutex;
    bool g_IsQuit = false;
    
    void QuitServer()
    {
    	while (!g_IsQuit)
    	{
    		short key = GetAsyncKeyState('A');
    		if(key&0x0001)
    		{
    			g_Mutex.lock();
    			g_IsQuit = true;
    			g_Mutex.unlock();
    		}
    		std::this_thread::sleep_for(std::chrono::milliseconds(1));
    	}
    }
    
    int main()
    {
    	//1.初始化网络环境
    	WORD wVersion = MAKEWORD(2, 2);
    	WSADATA wsaData;
    	int err = WSAStartup(wVersion, &wsaData);
    
    	if (err != 0)
    	{
    		printf("网络初始化错误,错误代码%d
    ", err);
    		system("pause");
    		return 0;
    	}
    
    	//2.创建监听套接字
    	SOCKET listenSock = socket(
    		AF_INET,
    		SOCK_STREAM,
    		IPPROTO_TCP
    	);
    	if (INVALID_SOCKET == listenSock)
    	{
    		printf("监听套接字创建失败
    ");
    		WSACleanup();
    		system("pause");
    		return 0;
    	}
    
    	//3.设置服务器的端口信息
    	sockaddr_in sin;
    	sin.sin_port = htons(6666);
    	sin.sin_family = AF_INET;
    	sin.sin_addr.S_un.S_addr = htonl(INADDR_ANY);//任意ip
    
    	//4.绑定地址信息到监听套接字
    	if (SOCKET_ERROR == bind(listenSock, (sockaddr*)&sin, sizeof(sin)))
    	{
    		printf("绑定监听套接字创建失败
    ");
    		closesocket(listenSock);
    		WSACleanup();
    		system("pause");
    		return 0;
    	}
    	//5.开始监听
    	if (SOCKET_ERROR == listen(listenSock, 100))
    	{
    		printf("监听出现错误
    ");
    		closesocket(listenSock);
    		WSACleanup();
    		system("pause");
    		return 0;
    	}
    
    	//6.收发信息
    	sockaddr_in clientaddinfo;
    	int addlen = sizeof(clientaddinfo);
    	SOCKET clientsock;
    
    	clientsock = accept(listenSock, (sockaddr*)&clientaddinfo, &addlen);
    
    
    	if (INVALID_SOCKET == clientsock)
    	{
    		printf("Accept错误
    ");
    		closesocket(listenSock);
    		WSACleanup();
    		system("pause");
    		
    		return 0;
    	}
    
    	//使用多线程转发和接收信息
    	while (!g_IsQuit)
    	{
    		printf("接收到一个客户:%d,IP:%s,Port:&d
    ",
    			clientsock,
    			inet_ntoa(clientaddinfo.sin_addr),
    			clientaddinfo.sin_port);
    		char buf[MAX_PATH] = {};
    		recv(clientsock, buf, MAX_PATH - 1, 0);
    		printf("接收到的数据:%s
    ", buf);
    
    		send(clientsock, "this is my backdata!", strlen("this is my backdata!") + 1,0);
    	}
    
    	//7.关闭套接字和网络环境
    	closesocket(clientsock);
    	closesocket(listenSock);
    	WSACleanup();
    	system("pause");
    	return 0;
    }
    

    Linux跨平台网络客户端

    #ifdef _WIN32
    #define WIN32_LEAN_AND_MEAN
    #define _WINSOCK_DEPRECATED_NO_WARNINGS
    #include <windows.h>
    #include <winsock2.h>
    #pragma comment(lib,"ws2_32.lib")
    #else
    #include <unistd.h>
    #include <arpa/inet.h>
    #include <string.h>
    
    #define MAX_PATH	260
    typedef int SOCKET;
    #define INVALID_SOCKET (SOCKET)(~0)
    #define SOCKET_ERROR			(-1)
    #define WSACleanup() //
    
    #endif
    #include <iostream>
    #include <thread>
    #include <mutex>
    #include <chrono>
    using namespace std;
    
    bool g_IsQuit = false;
    bool g_IsSend = false;
    char g_SendBuffer[MAX_PATH];
    mutex g_Mutex1;
    mutex g_Mutex2;
    
    void InputData()
    {
    	while (!g_IsQuit )
    	{
    		printf("input msg:
    ");
    		scanf("%s",g_SendBuffer);
    		if (strcmp(g_SendBuffer,"exit")==0)
    		{
    			g_Mutex1.lock();
    			g_IsQuit = true;
    			g_Mutex1.unlock();
    			break;
    		}else if (!g_IsSend)
    		{
    			g_Mutex2.lock();
    			g_IsSend = true;
    			g_Mutex2.unlock();
    		}
    		this_thread::sleep_for(chrono::milliseconds(1));
    	}
    }
    
    
    
    int main()
    {
    	#ifdef _WIN32
    	WORD wVersion = MAKEWORD(2, 2);
    	WSADATA wsaData;
    	int err = WSAStartup(wVersion, &wsaData);
    	if (err != 0)
    	{
    		printf("初始化错误%d
    ", err);
    		system("pause");
    		return 0;
    	}
    	#endif
    
    	SOCKET clientSock = socket(
    		AF_INET,
    		SOCK_STREAM,
    		IPPROTO_TCP
    		);
    
    	if (INVALID_SOCKET == clientSock)
    	{
    		printf("create clientsocket failed
    ");
    		WSACleanup();
    		system("pause");
    		return 0;
    	}
    
    	sockaddr_in sin;
    	sin.sin_port = htons(12345);
    	sin.sin_family = AF_INET;
    	#ifdef _WIN32
    	sin.sin_addr.S_un.S_addr = inet_addr("192.168.1.2");
    	#else 
    	sin.sin_addr.s_addr = inet_addr("192.168.1.2");
    	#endif
    
    	if (SOCKET_ERROR == connect(clientSock, (sockaddr*)&sin, sizeof(sin)))
    	{
    		printf("错误
    ");
    		#ifdef _WIN32
    		closesocket(clientSock);
    		#else
    		close(clientSock);
    		#endif
    		WSACleanup();
    		system("pause");
    		return 0;
    	}
    
    	thread inputthread(InputData);
    	inputthread.detach();
    
    
    	char recvdata[MAX_PATH] = {};
    	while (!g_IsQuit)
    	{
    		if (g_IsSend)
    		{
    			printf("start send data
    ");
    			send(clientSock,g_SendBuffer, strlen(g_SendBuffer) + 1, 0);
    			printf("start recv data
    ");
    			recv(clientSock, recvdata, MAX_PATH, 0);
    			printf("reved msg:%s
    ", recvdata);
    			g_Mutex2.lock();
    			g_IsSend = false;
    			g_Mutex2.unlock();
    			printf("lock end
    ");
    		}
    		this_thread::sleep_for(chrono::milliseconds(1));
    	}
    
    	#ifdef _WIN32
    	closesocket(clientSock);
    	#else
    	close(clientSock);
    	#endif
    	WSACleanup();
    	return 0;
    }
    

    总结

    • 跨平台注意编码
    • 通过使用内置的宏,可以进行操作系统判断 #ifdef _WIN32 #endif
    • arpa/inet.h:IP地址转换
  • 相关阅读:
    201521123038 《Java程序设计》 第五周学习总结
    201521123020 《Java程序设计》第4周学习总结
    201521123020 《Java程序设计》第3周学习总结
    201521123020《Java程序设计》第2周学习总结
    Java第十二周学习总结
    Java第十一周学习总结
    Java第十周学习总结
    Java第九周学习总结
    Java第八周学习总结
    Java第七周学习总结
  • 原文地址:https://www.cnblogs.com/biu-we/p/13261114.html
Copyright © 2011-2022 走看看