重点:
服务进程使用TCP通信,TCP又转而使用IP通信, IP再通过某种形式的数据链路层通信。
客户与服务器之间的信息流在其中一端是向下通过协议栈的, 跨越网络之后, 在另一端是向上通过协议栈的。
另外, 客户和服务器通常是用户进程, 而TCP和IP协议通常是内核中协议的一部分。(表示应用程序本身并不关心系统是如何进行通信处理的)
例:
客户端:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <string.h>
#include <sys/socket.h>
typedef struct sockaddr_in sockaddr_in;
typedef struct sockaddr sockaddr;
int
main(int argc, char * argv[])
{
int sockfd, n;
socklen_t len = sizeof(sockaddr);
char buff[1024];
do {
if (argc < 2)
exit(-1);
if (sockfd = socket(AF_INET, SOCK_STREAM, 0), sockfd < 0) {
printf("socket error\n");
break;
}
sockaddr_in saddr = {0};
saddr.sin_family = AF_INET;
saddr.sin_port = htons(6688);
if (inet_pton(AF_INET, argv[1], &saddr.sin_addr) <= 0) {
printf("inet_pton error\n");
break;
}
if (connect(sockfd, &saddr, len) < 0) {
printf("connect error\n");
break;
}
while (n = read(sockfd, buff, 1024), n > 0) {
buff[n] = 0;
printf("%s\n", buff);
}
} while (0);
exit(0);
}
服务端:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
typedef struct sockaddr_in sockaddr_in;
typedef struct sockaddr sockaddr;
int
main(int argc, char * argv[])
{
int sockfd, slen = sizeof(sockaddr), connfd;
time_t ticks;
char buff[1024];
do {
if (sockfd = socket(AF_INET, SOCK_STREAM, 0), sockfd < 0) {
printf("socket error\n");
break;
}
sockaddr_in saddr = {0};
saddr.sin_family = AF_INET;
saddr.sin_port = htons(6688);
saddr.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(sockfd, (sockaddr *)&saddr, slen) < 0) {
printf("bind error\n");
break;
}
if (listen(sockfd, 10) < 0) {
printf("listen error\n");
break;
}
for (;;) {
if (connfd = accept(sockfd, NULL, NULL), connfd < 0) {
if (errno == EINTR)
continue;
else
printf("accept error\n");
}
ticks = time(NULL);
snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks));
/*这里为了作习题所以才一个字节一个字节传的*/
int i, n;
for (i = 0, n = strlen(buff); i < n; i++)
write(connfd, &buff[i], 1);
close(connfd);
}
} while (0);
exit(0);
}
难点:
分节:计算机各层对等实体间交换的单位信息称为协议数据单元(protocol data unit, PDU), 分节就是对应TCP传输层的PDU。
每层的PDU通过由紧邻下层提供给本层的服务接口, 作为下层的服务数据单元(service data unit, SDU), 传递给下层。
如果本层的PUD大小超过紧邻下层的最大SDU限制, 那么本层还要事先把PDU划分成若干个合适的片段让下层分开载送, 再在相反方向把这些片段重组成PDU。
应用层实体间交换的PDU称为应用数据。
传输层实体间交换的PDU称为消息, 其中TCP的PDU特称为分节。
网络层实体间交换的PDU称为IP数据报。
链路层实体间交换的PDU称为帧。
链路层封装在帧中的数据称为分组, 俗称包。
TCP本身并不提供记录结束标志, 如果应用程序需要确定记录的边界, 它就要自己去实现。
OSI模型 网际网协议族
7 应用层 应用层
6 表示层
5 会话层
4 传输层 TCP/UDP
3 网络层 IPV4/IPV6
2 数据链路层 设备驱动程序和硬件
1 物理层