第一章:理解网络编程和套接字

本文深入探讨了在Linux和Windows平台上进行套接字编程的方法,通过电话比喻生动解释了连接建立过程,并详细对比了两种操作系统下文件描述符、I/O函数及套接字操作的异同。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.在linux中进行套接字编程的基本步骤(了解初识)

作者用了一个很贴合实际生活的例子(打电话)来比喻建立套接字连接的过程:

 建立连接的过程其实有点繁琐,记Bind listen什么的太伤脑筋了,先理解这个打电话的过程,然后在去记过程中每个步骤对应的函数会简单一些。

 


2.基于Linux的文件操作

这一节作者主要想说在linux中socket操作和文件操作没有区别,socket也是文件的一种。

首先,我们要理解文件描述符(file descriptor)的概念。文件描述符就是系统分配给文件或套接字的一个整数用来唯一标识这个文件或套接字。文件或套接字一般经过创建过程才会被分配文件描述符。然后举了write和read的例子,直接看书上就好了在此不多i赘述。

 


3.基于windows平台的实现

在windows上的实现与Linux上差不多,与Linux不同的是还要链接lib库。本书中Linux的操作和代码本人都经过执行没有问题,但是windows上操作和代码与本书中的有些变动所以我详述下。首先我的IDE是VS2017,在这个IDE环境下本书中这个小节的代码会出现编译出错的情况,所以我特意去网上抄了份类似的代码:

/* 服务端 */

#include <winSock2.h>
#include <cstdio>
#pragma comment (lib,"ws2_32.lib")

int main() {
	//初始化DLL
	WSADATA wsdata;
	WSAStartup(MAKEWORD(2, 2), &wsdata);

	//创建套接字
	SOCKET servsock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);

	//绑定套接字
	sockaddr_in sockaddr;
	memset(&sockaddr, 0, sizeof(sockaddr)); 
	sockaddr.sin_family = PF_INET;  //使用IPV4地址
	sockaddr.sin_addr.s_addr = inet_addr("127.0.0.1");  //具体的IP地址
	sockaddr.sin_port = htons(1234);  //端口
	bind(servsock, (SOCKADDR*)&sockaddr, sizeof(SOCKADDR));

	//进入监听状态
	listen(servsock, 20);

	//接收客户端请求
	SOCKADDR clntaddr;
	int nsize = sizeof(SOCKADDR);
	SOCKET clntsock = accept(servsock, (SOCKADDR*)&clntaddr, &nsize);

	//向客户端发送数据
	const char* str = "helloworld";
	send(clntsock,str,10+sizeof(char),NULL);

	//关闭套接字
	closesocket(clntsock);
	closesocket(servsock);

	//终止DLL
	WSACleanup();
	return 0;
}
/*客户端*/
#include <cstdio>
#include <cstdlib>
#include <WinSock2.h>
#pragma comment(lib,"ws2_32.lib")
char szBuffer[128] = { 0 };

int main() {
	WSADATA wsadata;
	WSAStartup(MAKEWORD(2, 2), &wsadata);

	//创建套接字
	SOCKET sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);

	//向服务器发起请求
	sockaddr_in sockaddr;
	memset(&sockaddr, 0, sizeof(sockaddr));
	sockaddr.sin_family = PF_INET;
	sockaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
	sockaddr.sin_port = htons(1234);
	connect(sock, (SOCKADDR*)&sockaddr, sizeof(SOCKADDR));

	//接收服务器传回的数据
	recv(sock, szBuffer, 128, NULL);
	//输出接收到的数据
	printf("Message from server: %s", szBuffer);
	//关闭套接字
	closesocket(sock);
	WSACleanup();
	system("pause");
	return 0;
}

然后,从代码可以看出,除了dll库的初始化和关闭,其他基本和linux上是一样的步骤。但是Linux上我们验证服务端和客户端通常是开两个终端,在一个终端先运行服务端,再在另一个终端运行客户端。在windows上同理,不过我们用的是 VS2017开发人员的命令提示符(以下简称VS终端),没错,这个终端就叫这个名字 。跟Linux上的操作一样,我们开两个VS终端,然后在一个终端先cl.exe server.cpp运行,再在另一个VS终端上cl.exe client.cpp运行。

 


4.基于windows的I/O函数

windows中用send,recv函数来进行socket的数据传输,但请不要误认为Linux中的read,write函数就是对应于windows的send,recv函数,在linux中也有send和recv函数。具体函数参数意义看书本。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值