目录
1.4.1.2.1 面向连接的套接字(SOCK_STREAM)
1.4.1.2.2 面向消息的套接字(SOCK_DGRAM)
2.1.6.2 inet_aton函数(Windows不存在此函数)
2.1.6.3 inet_ntoa函数(和inet_aton函数相反)
2.1.6.5 WSAStringToAddress函数(只有Windows平台有,不利于兼容性)
2.1.6.6 WSAAddressToString函数(只有Windows平台有,不利于兼容性)
2.1.6.7 服务器端初始化IP地址时非常明确,为什么还要进行IP的初始化呢?
网络编程:编写程序使两台连网的计算机进行数据交换。
1. 套接字
操作系统提供名为套接字的部件,套接字是网络数据传输用的软件设备,它能够连接到因特网上,与远程计算机进行数据传输。
1.1 在Linux平台下构建套接字
对于Linux而言,socket操作与文件操作没有区别。如:close函数不仅可以关闭文件也可以关闭套接字。
1.1.1 用于接听的套接字(服务器端套接字)
第一步:调用socket函数创建套接字
#include<sts/socket.h>
int socket(int domain,int type,int protocol);
成功返回文件描述符,失败返回-1
第二步:调用bind函数分配IP地址和端口号
#include<sts/socket.h>
int bind(int sockfd,struct sockaddr* myaddr,socklen_t addrlen);
成功返回0,失败返回-1
第三步:调用listen函数转为可接收请求状态
#include<sts/socket.h>
int listen(int sockfd,int backlog);
成功返回0,失败返回-1
第四步:调用accept函数受理连接请求
#include<sts/socket.h>
int accept(int sockfd,struct sockaddr* addr,socklen_t* addrlen);
成功返回文件描述符,失败返回-1
accpet函数一直等待,直到有连接请求时,才会有返回值。
第五步:调用write函数发送数据
#include<unistd.h>
ssize_t write(int fd,const void* buf,size_t nbytes);
成功则返回写入的字节数,失败返回-1
fd:文件描述符参数
buf:保存要传输数据的缓冲地址值
nbytes:要传输数据的字节数
第六步:关闭套接字
#include<unistd.h>
int close(int fd);
成功返回0,失败返回-1
fd:文件描述符参数。
close函数不仅可以关闭文件也可以关闭套接字。 客户端调用close会向服务端的客户端套接字文件描述符传递EOF。
1.1.2 用于发送请求的套接字(客户端套接字)
第一步:调用socket函数创建套接字
如上。
第二步:调用connect函数连接服务器端
#include<sts/socket.h>
int connect(int sockfd,struct sockaddr* serv_addr,socklen_t addrlen);
成功返回0,失败返回-1
第三步:调用read函数读取服务器传输的信息
#include<unistd.h>
ssize_t read(int fd,void *buf,size_t nbytes);
成功则返回接收的字节数(但遇到文件结尾则返回0),失败返回-1
fd:数据接收对象的文件描述符参数
buf:保存接收数据的缓冲地址值
nbytes:要接收数据的字节数
第四步:关闭套接字
如上。
1.2 在Windows平台下构建套接字
在Windows平台下构建套接字要先进行Winsock的初始化。
1.2.1 Winsock的初始化
初始化版本库
#include<winsock2.h>
int WSAStartup(WORD wVersionRequested,LPWSADATA lpWSAData);
成功返回0,失败返回非0的错误代码值
wVersionRequested:WORD是通过typedef定义的unsigned short类型,这个参数是提供套接字版本信息。可借助MAKEWORD宏函数来构建版本信息,如:
MAKEWORD(1,2); //主版本为1,副版本为2,返回0x0201
MAKEWORD(2,2); //主版本为2,副版本为2,返回0x0202
lpWSAData:传入WSADATA型结构体变量地址(LPWSADATA是WSADATA的指针类型),调用完函数后会将相关参数,填充到这个参数里。
WSADATA wsaData;
if(WSAStartup(MAKEWORD(2,2),&wsaData)!=0)
{
......
}
注销版本库
#include<winsock2.h>
int WSACleanup(void);
成功返回0,失败返回SOCKET_ERROR
销毁Winsock相关库,无法再调用Winsock相关函数。
1.2.2 用于接听的套接字(服务器端套接字)
第一步:调用socket函数创建套接字
#include <winsock2.h>
SOCKET socket(int af,int type,int protocol);
成功返回套接字句柄,失败返回INVALID_SOCKET
第二步:调用bind函数分配IP地址和端口号
#include <winsock2.h>
int bind(SOCKET s,const struct sockaddr* name,int namelen);
成功返回0,失败返回SOCKET_ERROR
第三步:调用listen函数转为可接收请求状态
#include <winsock2.h>
int listen(SOCKET s,int backlog);
成功返回0,失败返回SOCKET_ERROR
第四步:调用accept函数受理连接请求
#include <winsock2.h>
SOCKET accept(SOCKET s,struct sockaddr* addr,int* addrlen);
成功返回文件描述符,失败返回INVALID_SOCKET
accpet函数一直等待,直到有连接请求时,才会有返回值。
第五步:调用send函数发送数据
#include<winsock2.h>
int send(SOCKET s,const char* buf,int len,int flags);
成功返回传输字节数,失败返回SOCKET_ERROR
s:表示数据传输对象连接的套接字句柄值
buf: 保存待传输数据的缓冲地址值
len:要传输的字节数
flags:传输数据时用到的多种选项信息
第六步:关闭套接字
#include <winsock2.h>
int closeconnect(SOCKET s);
成功返回0,失败返回SOCKET_ERROR
1.2.3 用于发送请求的套接字(客户端套接字)
第一步:调用socket函数创建套接字
如上。
第二步:调用connect函数连接服务器端
#include <winsock2.h>
int connect(SOCKET s,const struct sockaddr* name,int namelen);
成功返回0,失败返回SOCKET_ERROR
第三步:调用recv函数,接收服务器端传来的数据
#include <winsock2.h>
int recv(SOCKET s,const char* buf,int len,int flags);
成功返回接收的字节数(收到EOF时为0),失败返回SOCKET_ERROR
s:表示数据接收对象连接的套接字句柄值
buf: 保存接收数据的缓冲地址值
len:要接收的最大字节数
flags:接收数据时用到的多种选项信息
第四步:关闭套接字
如上。