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函数。具体函数参数意义看书本。