在 TCP/IP 中包含一系列用于处理数据通信的协议:
- TCP (传输控制协议) - 应用程序之间通信
- UDP (用户数据包协议) - 应用程序之间的简单通信
- IP (网际协议) - 计算机之间的通信
- ICMP (因特网消息控制协议) - 针对错误和状态
- DHCP (动态主机配置协议) - 针对动态寻址
TCP - 传输控制协议 (Transmission Control Protocol)
TCP 用于从应用程序到网络的数据传输控制。
TCP 负责在数据传送之前将它们分割为 IP 包,然后在它们到达的时候将它们重组。
UDP - 用户数据报协议 (User Datagram Protocol)
UDP 是User Datagram Protocol的简称, 中文名是用户数据报协议,是 OSI 参考模型中一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务,IETF RFC 768是UDP的正式规范。UDP是OSI参考模型中一种无连接的传输层协议,它主要用于不要求分组顺序到达的传输中,分组传输顺序的检查与排序由应用层完成,提供面向事务的简单不可靠信息传送服务。UDP 协议基本上是IP协议与上层协议的接口。UDP协议适用端口分别运行在同一台设备上的多个应用程序。
HTTP - 超文本传输协议(Hyper Text Transport Protocol)
HTTP 负责 web 服务器与 web 浏览器之间的通信。
HTTP 用于从 web 客户端(浏览器)向 web 服务器发送请求,并从 web 服务器向 web 客户端返回内容(网页)。
SMTP - 简易邮件传输协议(Simple Message Transfer Protocol)
SMTP 协议用于传输电子邮件。SMTP 负责把邮件发送到另一台计算机。
通常情况下,邮件会被送到一台邮件服务器(SMTP 服务器),然后被送到另一台(或几台)服务器,然后最终被送到它的目的地。
SMTP 也可以传送纯文本,但是无法传输诸如图片、声音或者电影之类的二进制数据。
SMTP 使用 MIME 协议通过 TCP/IP 网络来发送二进制数据。MIME 协议会将二进制数据转换为纯文本。
MIME - 多用途因特网邮件扩展 (multipurpose internet mail extensions)
MIME 协议使 SMTP 有能力通过 TCP/IP 网络传输多媒体文件,包括声音、视频和二进制数据。
IMAP - 因特网消息访问协议(Internet Message Access Protocol)
与 POP 类似,IMAP 协议同样被邮件程序使用。
IMAP 协议与 POP 协议之间的主要差异是:如果 IMAP 连上了邮件服务器,它不会自动地将邮件下载到邮件程序之中。
IMAP 使你有能力在下载邮件之前先通过邮件服务器端查看他们。通过 IMAP,你可以选择下载这些邮件或者仅仅是删除它们。比方说你需要从不同的位置访问邮件服务器,但是仅仅希望回到办公室的时候再下载邮件,IMAP 在这种情况下会很有用。
POP - 邮局协议(post office protocol)
POP 协议被邮件程序用来取回邮件服务器上面的邮件。
假如你的邮件程序使用 POP,那么一旦它连接上邮件服务器,你的所有的邮件都会被下载到邮件程序中(或者称之为邮件客户端)。
{
//1 加载套接字库
WORD wVersionRequested;//版本号
WSADATA wsaData;//windows socket数据,包含了版本信息
int err;
wVersionRequested = MAKEWORD( 1, 1 );//版本号1.1
err = WSAStartup( wVersionRequested, &wsaData );//加载套接字库
if ( err != 0 )
{
return;
}
//判断版本是否一致
if ( LOBYTE( wsaData.wVersion ) != 1 ||HIBYTE( wsaData.wVersion ) != 1 )
{
WSACleanup();//如果版本不是1.1就终止对套接字库的使用退出
return;
}
//2 创建套接字
//第1个参数指定地址族
//第2个参数指定socket类型,SOCK_STREAM指定产生流式套接字
//第3个参数是与特定的地址族相关的协议,0表示系统会自动选择一个合适协议
SOCKET sockSrv=socket(AF_INET,SOCK_STREAM,0);
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);//INADDR_ANY表示绑定多任意一个地址(某些服务器有多个网卡,所以有多个IP地址),
addrSrv.sin_family=AF_INET;//TCP/IP协议必须使用AF_INET
addrSrv.sin_port=htons(6000);//端口
//3 将套接字绑定到一个本地的地址和端口上
bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
//4 将套接字设为监听模式,准备接受客户请求
listen(sockSrv,5);
//5 等待客户请求到来
SOCKADDR_IN addrClient;//接收的客户端的地址信息
int len=sizeof(SOCKADDR);
while(1)
{
//接受客户的连接请求
SOCKET sockConn=accept(sockSrv,(SOCKADDR*)&addrClient,&len);
char sendBuf[100];
sprintf(sendBuf,"Welcome %s to http://www.sunxin.org",
inet_ntoa(addrClient.sin_addr));
//向客户端发送数据
send(sockConn,sendBuf,strlen(sendBuf)+1,0);
char recvBuf[100];
//从客户端接收数据
recv(sockConn,recvBuf,100,0);
printf("%s\n",recvBuf);
//当前通信完成,关闭已建立的套接字
closesocket(sockConn);
}
}
#include <stdio.h>
void main()
{
//1 加载套接字库
WORD wVersionRequested;//版本号
WSADATA wsaData;//windows socket数据,包含了版本信息
int err;
wVersionRequested = MAKEWORD( 1, 1 );//版本号1.1
err = WSAStartup( wVersionRequested, &wsaData );//加载套接字库
if ( err != 0 )
{
return;
}
//判断版本是否一致
if ( LOBYTE( wsaData.wVersion ) != 1 || HIBYTE( wsaData.wVersion ) != 1 )
{
WSACleanup( );//如果版本不是1.1就终止对套接字库的使用并退出
return;
}
//2 创建套接字库
//第1个参数指定地址族
//第2个参数指定socket类型,SOCK_STREAM指定产生流式套接字
//第3个参数是与特定的地址族相关的协议,0表示系统会自动选择一个合适协议
SOCKET sockClient=socket(AF_INET,SOCK_STREAM,0);
//3 向服务器发出连接请求
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");//使用本地回路地址,无论本机是否有网卡,都可以使用该IP地址
addrSrv.sin_family=AF_INET;//TCP/IP协议必须使用AF_INET
addrSrv.sin_port=htons(6000);//端口
connect(sockClient,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
//4 和服务器通信
char recvBuf[100];
//接收数据
recv(sockClient,recvBuf,100,0);
printf("%s\n",recvBuf);
//发送数据
send(sockClient,"This is lisi",strlen("This is lisi")+1,0);
//5 关闭套接字
closesocket(sockClient);
//6 终止对套接字库的使用
WSACleanup();
}
#include <stdio.h>
void main()
{
//1 加载套接字库
WORD wVersionRequested;//版本号
WSADATA wsaData;//windows socket数据,包含了版本信息
int err;
wVersionRequested = MAKEWORD( 1, 1 );//版本号1.1
err = WSAStartup( wVersionRequested, &wsaData );//加载套接字库
if ( err != 0 )
{
return;
}
//判断版本是否一致
if ( LOBYTE( wsaData.wVersion ) != 1 || HIBYTE( wsaData.wVersion ) != 1 )
{
WSACleanup( );//如果版本不是1.1就终止对套接字库的使用并退出
return;
}
//2 创建套接字库
//第1个参数指定地址族
//第2个参数指定socket类型,SOCK_DGRAM指定产生数据报套接字
//第3个参数是与特定的地址族相关的协议,0表示系统会自动选择一个合适协议
SOCKET sockSrv=socket(AF_INET,SOCK_DGRAM,0);
//3 将套接字绑定到一个本地的地址和端口上
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);//INADDR_ANY表示绑定多任意一个地址(某些服务器有多个网卡,所以有多个IP地址),
addrSrv.sin_family=AF_INET;
addrSrv.sin_port=htons(6000);//端口
bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
//3 等待接收数据(注意基于UDP的网络程序使用的是recvfrom)
SOCKADDR_IN addrClient;
int len=sizeof(SOCKADDR);
char recvBuf[100];
recvfrom(sockSrv,recvBuf,100,0,(SOCKADDR*)&addrClient,&len);
printf("%s\n",recvBuf);
//关闭套接字
closesocket(sockSrv);
//终止对套接字库的使用
WSACleanup();
}
#include <stdio.h>
void main()
{
//1 加载套接字库
WORD wVersionRequested;//版本号
WSADATA wsaData;//windows socket数据,包含了版本信息
int err;
wVersionRequested = MAKEWORD( 1, 1 );//版本号1.1
err = WSAStartup( wVersionRequested, &wsaData );//加载套接字库
if ( err != 0 )
{
return;
}
//判断版本是否一致
if ( LOBYTE( wsaData.wVersion ) != 1 || HIBYTE( wsaData.wVersion ) != 1 )
{
WSACleanup( );//如果版本不是1.1就终止对套接字库的使用并退出
return;
}
//2 创建套接字库
//第1个参数指定地址族
//第2个参数指定socket类型,SOCK_DGRAM指定产生数据报套接字
//第3个参数是与特定的地址族相关的协议,0表示系统会自动选择一个合适协议
SOCKET sockClient=socket(AF_INET,SOCK_DGRAM,0);
//3 向服务器发送数据
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");//使用本地回路地址,无论本机是否有网卡,都可以使用该IP地址
addrSrv.sin_family=AF_INET;
addrSrv.sin_port=htons(6000);//端口
sendto(sockClient,"Hello",strlen("Hello")+1,0,
(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
//关闭套接字
closesocket(sockClient);
//终止对套接字库的使用
WSACleanup();
}
#include <stdio.h>
void main()
{
//1 加载套接字库
WORD wVersionRequested;//版本号
WSADATA wsaData;//windows socket数据,包含了版本信息
int err;
wVersionRequested = MAKEWORD( 1, 1 );//版本号1.1
err = WSAStartup( wVersionRequested, &wsaData );//加载套接字库
if ( err != 0 )
{
return;
}
//判断版本是否一致
if ( LOBYTE( wsaData.wVersion ) != 1 || HIBYTE( wsaData.wVersion ) != 1 )
{
WSACleanup( );//如果版本不是1.1就终止对套接字库的使用并退出
return;
}
//2 创建套接字库
//第1个参数指定地址族
//第2个参数指定socket类型,SOCK_DGRAM指定产生数据报套接字
//第3个参数是与特定的地址族相关的协议,0表示系统会自动选择一个合适协议
SOCKET sockSrv=socket(AF_INET,SOCK_DGRAM,0);
//3 将套接字绑定到一个本地的地址和端口上
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);//INADDR_ANY表示绑定多任意一个地址(某些服务器有多个网卡,所以有多个IP地址)
addrSrv.sin_family=AF_INET;
addrSrv.sin_port=htons(6000);//端口
bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
char recvBuf[100];
char sendBuf[100];
char tempBuf[200];
SOCKADDR_IN addrClient;
int len=sizeof(SOCKADDR);
while(1)
{
//等待并接收数据
recvfrom(sockSrv,recvBuf,100,0,(SOCKADDR*)&addrClient,&len);
if('q'==recvBuf[0])
{
//第一个字符是q,表示要退出聊天程序,于是给对方也发送一个q
sendto(sockSrv,"q",strlen("q")+1,0,(SOCKADDR*)&addrClient,len);
printf("Chat end!\n");
break;//退出循环
}
sprintf(tempBuf,"%s say : %s",inet_ntoa(addrClient.sin_addr),recvBuf);
printf("%s\n",tempBuf);
//发送数据
printf("Please input data:\n");
gets(sendBuf);
sendto(sockSrv,sendBuf,strlen(sendBuf)+1,0,(SOCKADDR*)&addrClient,len);
}
closesocket(sockSrv);//关闭套接字
WSACleanup();//结束套接字库的使用
}
#include <stdio.h>
void main()
{
//1 加载套接字库
WORD wVersionRequested;//版本号
WSADATA wsaData;//windows socket数据,包含了版本信息
int err;
wVersionRequested = MAKEWORD( 1, 1 );//版本号1.1
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 )
{
return;
}
//判断版本是否一致
if ( LOBYTE( wsaData.wVersion ) != 1 || HIBYTE( wsaData.wVersion ) != 1 )
{
WSACleanup( );//如果版本不是1.1就终止对套接字库的使用并退出
return;
}
//2 创建套接字库
//第1个参数指定地址族
//第2个参数指定socket类型,SOCK_DGRAM指定产生数据报套接字
//第3个参数是与特定的地址族相关的协议,0表示系统会自动选择一个合适协议
SOCKET sockClient=socket(AF_INET,SOCK_DGRAM,0);
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
addrSrv.sin_family=AF_INET;
addrSrv.sin_port=htons(6000);
char recvBuf[100];
char sendBuf[100];
char tempBuf[200];
int len=sizeof(SOCKADDR);
while(1)
{
printf("Please input data:\n");
gets(sendBuf);
//发送数据
sendto(sockClient,sendBuf,strlen(sendBuf)+1,0,
(SOCKADDR*)&addrSrv,len);
//接收数据
recvfrom(sockClient,recvBuf,100,0,(SOCKADDR*)&addrSrv,&len);
if('q'==recvBuf[0])
{
sendto(sockClient,"q",strlen("q")+1,0,
(SOCKADDR*)&addrSrv,len);
printf("Chat end!\n");
break;
}
sprintf(tempBuf,"%s say : %s",inet_ntoa(addrSrv.sin_addr),recvBuf);
printf("%s\n",tempBuf);
}
closesocket(sockClient);//关闭套接字
WSACleanup();//结束套接字库的使用
}