网络编程:实现一个基于Windows的服务端/客户端程序

widows下使用socket套接字进行网络通信的步骤与Linux下差异不大,基本的调用流程也是相似的,即使内部的实现有所不同。

以下是服务器端的代码实现:

#include <iostream>
#include <stdlib.h>
#include <WinSock2.h>
using namespace std;

int main(int argc, char* argv[])
{
	if (argc != 2)
	{
		cout << "invalid parameter! add port!" << endl;
		exit(1);
	}

	WSADATA wsaData;
	SOCKET servSock, clntSock;
	SOCKADDR_IN servAddr, clntAddr;
	int clntAddrLen;

	// 设置程序中用到的Winsock版本,并初始化相应版本的库
	if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
	{
		cout << "WSAStartup() error" << endl;
		exit(1);
	}

	// 创建socket套接字
	servSock = socket(PF_INET, SOCK_STREAM, 0);
	if (servSock == INVALID_SOCKET)
	{
		cout << "socket() error" << endl;
		exit(1);
	}

	// 设置服务端的地址信息:IP、端口、协议族
	memset(&servAddr, 0, sizeof(servAddr));
	servAddr.sin_family = AF_INET;
	servAddr.sin_addr.s_addr = htonl(INADDR_ANY);
	servAddr.sin_port = htons(atoi(argv[1]));

	// 绑定IP和端口
	if (bind(servSock, (SOCKADDR*)&servAddr, sizeof(servAddr)) == SOCKET_ERROR)
	{
		cout << "bind() error" << endl;
		exit(1);
	}

	// 在所绑定的端口号做监听
	if (listen(servSock, 5) == SOCKET_ERROR)
	{
		cout << "listen() error" << endl;
		exit(1);
	}

	// 接收来自客户端的连接请求
	clntAddrLen = sizeof(clntAddr);
	clntSock = accept(servSock, (SOCKADDR*)&clntAddr, &clntAddrLen);
	if (clntSock == INVALID_SOCKET)
	{
		cout << "accept() error" << endl;
		exit(1);
	}

	// 向客户端发送数据
	char message[] = "Hello, It's servers!";
	send(clntSock, message, sizeof(message), 0);

	// 关闭套接字连接
	closesocket(servSock);
	closesocket(clntSock);

	// 注销使用的Winsock库
	WSACleanup();

	return EXIT_SUCCESS;
}

以下是客户端的代码实现:

#define _WINSOCK_DEPRECATED_NO_WARNINGS 
#include <iostream>
#include <stdlib.h>
#include <WinSock2.h>
using namespace std;

int main(int argc, char* argv[])
{
	// 检查输入参数的合法性
	if (argc != 3)
	{
		cout << "invalid parameter! add ip and port!" << endl;
		exit(1);
	}

	WSADATA wsaData;
	SOCKET clntSocket;
	SOCKADDR_IN servAddr;

	// 设置程序中用到的Winsock版本,并初始化相应版本的库
	if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
	{
		cout << "WSAStartup() error" << endl;
		exit(1);
	}

	// 创建socket套接字
	clntSocket = socket(PF_INET, SOCK_STREAM, 0);
	if (clntSocket == INVALID_SOCKET)
	{
		cout << "socket() error" << endl;
		exit(1);
	}

	// 设置服务器端的地址信息:IP、端口、协议族
	memset(&servAddr, 0, sizeof(servAddr));
	servAddr.sin_family = AF_INET;
	servAddr.sin_addr.s_addr = inet_addr(argv[1]);
	servAddr.sin_port = htons(atoi(argv[2]));

	// 创建连接
	if (connect(clntSocket, (SOCKADDR*)&servAddr, sizeof(servAddr)) == SOCKET_ERROR)
	{
		cout << "connect() error" << endl;
		exit(1);
	}

	// 接收来自服务器端的数据
	char message[100] = { 0 };
	int msglen = recv(clntSocket, message, sizeof(message) - 1, 0);
	if (msglen == -1)
	{
		cout << "recv() error" << endl;
		exit(1);
	}

	cout << "msg from server : " << message << endl;

	// 关闭套接字连接
	closesocket(clntSocket);

	// 注销使用的Winsock库
	WSACleanup();

	return 0;
}

在VS中编译后,生成可执行文件。然后使用cmd,分别运行客户端和服务器端程序,服务器端监听8888端口,而客户端绑定本地IP和8888端口,与服务器端建立链接。

客户端程序执行结果:建立连接成功后,收到来自服务器端的信息数据。
客户端执行结果

服务器端执行结果:开始时创建套接字,然后等待客户端的连接,没有任何输出,一旦客户端连接成功后,发送消息,然后直接运行结束。在这里插入图片描述

谢谢阅读。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值