用网络编程完成windows和linux跨平台之间的通信(服务器)

服务器代码逻辑:

服务器功能

  1. 创建 Socket

    • 服务器首先创建一个 Socket 对象,用于进行网络通信。通常使用 socket() 函数创建。
  2. 绑定(Bind)

    • 服务器将 Socket 绑定到一个特定的 IP 地址和端口号上。这是通过 bind() 函数实现的,目的是告诉操作系统服务器将监听哪个 IP 地址和端口号上的连接请求。
  3. 监听(Listen)

    • 服务器将 Socket 设置为监听模式,准备接受来自客户端的连接请求。这是通过 listen() 函数实现的,通常需要指定一个待处理的连接队列的大小。
  4. 接受连接(Accept)

    • 服务器等待客户端的连接请求。当一个客户端请求连接时,服务器通过 accept() 函数接受连接,并为每个连接创建一个新的 Socket。服务器可以在不同的线程或进程中处理多个客户端连接。
  5. 处理数据(Read/Write)

    • 一旦连接建立,服务器和客户端可以通过已建立的 Socket 进行数据的读写操作。这是通过 recv()send() 函数实现的。
  6. 关闭连接(Close)

    • 当数据传输完成或连接结束时,服务器使用 close() 函数关闭 Socket,释放资源。

windows打开服务器: 

#ifdef _WIN64
#define WIN32
#endif
#ifdef WIN32
#include <Windows.h>
#define socklen_t int
#else
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>

#define  closesocket close
#endif
#include <stdio.h>
#include<string.h>
#include<stdlib.h>
#include<thread>

using namespace std;
class TcpThread
{
public:
	void Main()
	{
		char buf[1024] = { 0 };
		for (;;)
		{
			int recvlen = recv(client, buf, sizeof(buf) - 1, 0);
			//从客户端套接字 client 中接收数据,存储到缓冲区 buf 中。
			//sizeof(buf) - 1 确保缓冲区有足够的空间来存储数据,并保留一个字节用于存储终止符。



			if (recvlen <= 0 || strstr(buf, "quit") != NULL)
			{
				char re[] = "quit success!\n";
				send(client, re, strlen(re) + 1, 0);//发送“quit success!”消息到客户端,然后退出循环。
				break;
			}
			buf[recvlen] = '\0';
			int sendlen = send(client, "ok\n", 4, 0);
			printf("recv %s\n", buf);
		}

		closesocket(client);//关闭客户端套接字,释放相关资源。
		delete this;//删除当前 TcpThread 对象,释放内存。
	}
	int client = 0;
};
int main(int argc, char* argv[])
{
#ifdef WIN32
	/声明一个 WSADATA 结构体变量 ws。WSADATA 是一个结构体,包含了 Windows Sockets 动态链接库(DLL)的详细信息。
	WSADATA ws;
	//WSAStartup 函数初始化 Winsock 库。
	//MAKEWORD(2, 2) 是一个宏,它创建一个 16 位的值,表示我们请求的 Winsock 版本号。在这里,MAKEWORD(2, 2) 表示我们请求 Winsock 2.2 版本。
	//&ws 是指向 WSADATA 结构体的指针,用于接收初始化的信息。
	WSAStartup(MAKEWORD(2, 2), &ws);
#endif




	int sock = socket(AF_INET, SOCK_STREAM, 0);
	//AF_INET表示用的IPV4协议,SOCK_STREAM表示面向连接的稳定数据传输(TCP)
	if (sock == -1)
	{
		printf("create socket failed!\n");
		return -1;
	}
	unsigned short port = 8080;
	if (argc > 1)
	{
		port = atoi(argv[1]);
	}




	//端口号、ip地址
	sockaddr_in saddr;//sockaddr_in 是一个结构体类型,用于存储 IPv4 地址信息。

	saddr.sin_family = AF_INET;//表示IPV4
	saddr.sin_port = htons(port);//转换默认x86小端,host to net 
	saddr.sin_addr.s_addr = htonl(0);//将IP地址设置为 0.0.0.0,表示绑定到所有可用的网络接口。




	//--------------
	if (::bind(sock, (sockaddr*)&saddr, sizeof(saddr)) != 0)
	{
		printf("bind port %d failed!\n", port);
		return -2;
	}
	printf("bind port %d success!\n", port);




	listen(sock, 10);//用于将套接字设为监听模式,使其可以接受传入的连接请求。10表示为套接字排队的最大连接个数




	for (;;)
	{
		sockaddr_in caddr;
		socklen_t len = sizeof(caddr);//socklen_t 是一个数据类型,用于表示套接字相关结构的大小
		int client = accept(sock, (sockaddr*)&caddr, &len);//成功时返回一个新的套接字文件描述符client,用于与已连接的客户端通信。
		if (client <= 0)break;
		printf("accept client %d\n", client);
		char* ip = inet_ntoa(caddr.sin_addr);//将 caddr.sin_addr 中存储的网络字节序的 IP 地址转换为点分十进制的字符串表示形式。
		unsigned short cport = ntohs(caddr.sin_port);//将 caddr.sin_port 中存储的网络字节序的端口号转换为主机字节序
		printf("client ip is %s,port is %d\n", ip, cport);



		TcpThread* th = new TcpThread();
		th->client = client;


		//创建一个新线程,并在该线程中执行 TcpThread 类的 Main 方法
		thread sth(&TcpThread::Main, th);//&TcpThread::Main 是指向 TcpThread 类成员函数 Main 的指针。th 是一个指向 TcpThread 对象的指针。
		sth.detach();
	}
	printf("%d", sock);
	closesocket(sock);
	return 0;
}

windows上直接运行该文件即可打开服务器等待客户端的连接 

linux连接服务器:

 在Putty上输入telnet 192.168.10.4 8080,telnet 192.168.10.4 8080 是一个命令,用于通过 Telnet 协议连接到指定的 IP 地址和端口号。具体来说,它尝试建立一个与 IP 地址 192.168.10.4 上端口 8080 的连接,如果你看到类似于“Connected to 192.168.10.4”这样的消息,说明端口 8080 上的服务正在监听,并且你已成功连接到该服务。这意味着你可以开始发送数据或与该服务交互。

注意  telnet后面的ip是服务器的ip, 

 

当然我们也可以将服务器和客户端都在windows上或linux上打开,我只是为了说明可以跨平台通信而已。 

在linux上编译运行服务器:

先进入该项目的文件夹,我的是test1项目文件夹,cd code, cd test1,在该文件夹下打开vim 编辑一个makefile,输入命令 vim makefile进入编辑页面,

然后输入make test1,即可编译成功,在.\ test1执行即可打开服务器 

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-11 15:56:02       67 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-11 15:56:02       71 阅读
  3. 在Django里面运行非项目文件

    2024-07-11 15:56:02       58 阅读
  4. Python语言-面向对象

    2024-07-11 15:56:02       69 阅读

热门阅读

  1. mysql select count返回null

    2024-07-11 15:56:02       19 阅读
  2. HTML 标签列表(功能排序)

    2024-07-11 15:56:02       21 阅读
  3. Hadoop HA ( 3.1.3 )

    2024-07-11 15:56:02       20 阅读
  4. 【智能制造-14】机器视觉软件

    2024-07-11 15:56:02       24 阅读
  5. Vue viewer 下通循环获取的图片无法预览问题

    2024-07-11 15:56:02       15 阅读
  6. sa-token前后端分离解决跨域的正确姿势

    2024-07-11 15:56:02       16 阅读
  7. MySQL 程序简介

    2024-07-11 15:56:02       21 阅读
  8. Day1 计数类dp 知识点 & 部分例题

    2024-07-11 15:56:02       22 阅读
  9. 【linux】精简版代码备份

    2024-07-11 15:56:02       24 阅读