知识点总结
一、TCP/IP协议
TCP/IP是互联网的基础,TCP代表传输控制协议,IP代表互联网协议。目前有IPv4(32位地址)和IPv6(128位地址),目前IPv4使用最多 。TCP/IP的四层结构如下:
层级 | 功能 | 组件 |
---|---|---|
应用层 | 向用户提供应用程序,如电子邮件、文件传输访问、远程登录等 | ssh, ping |
传输层 | 提供应用程序间的通信,格式化信息流,提供可靠传输 | TCP, UDP |
网络层 | 进行网络连接的建立和终止及IP地址的寻找最佳途径等 | IP |
网络接口层 | 传输数据的物理媒介 | Ethernet |
2. IP主机和IP地址
主机是支持TCP/IP 协议的计算机或设备。每个主机由一个32位的IP地址来标识。为了方便起见,32位的P地址号通常用点记法表示,例如:134.121.64.1,其中各个字节用点号分开。主机也可以用主机名来表示,如dns1.eec.wsu.edu。IP地址分为两部分,即 NetworkID字段和HostID字段。根据划分,IP地址分为A~E类。例如,一个B类P地址被划分为一个16位NetworkID,其中前2位是10,然后是一个16位的HostID字段。发往P地址的数据包首先被发送到具有相同networkID 的路由器。路由器将通过HostID将数据包转发到网络中的特定主机。每个主机都有一个本地主机名localhost,默认P地址为127.0.0.1。本地主机的链路层是一个回送虚拟设备,它将每个数据包路由回同一个 localhost。
套接字API
在网络编程中,TCP/IP的用户界面是通过一系列C语言库函数和系统调用来实现的,这些函数和系统调用统称为套接字API((Rago1993;Stevens等2004)。为了使用套接字 API,我们需要套接字地址结构,它用于标识服务器和客户机。netdbh和sys/socketh中有套接字地址结构的定义。
struct sockaddr_in {
sa_family_t sin_family; // AF_INET for TCP/IP
in port_t sinport; // port number
struct in_addr sin_addr; // IP address
};
struct in_addr{ //internet address
uint32_t s_addr; // IP address in network byte order
};
二、苏格拉底大挑战
三、代码实践
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <time.h>
#include <string.h>
#include <unistd.h>
#define MAXLINE 256
#define PORT 7777
void sys_err(char *msg)
{
perror(msg);
exit(-1);
}
int main(int argc , char **argv)
{
int sockFd,n;
char recvLine[MAXLINE];
struct sockaddr_in servAddr;
if (argc != 2)
{
sys_err("usage: a.out <IPaddress>");
}
sockFd=socket(AF_INET,SOCK_STREAM,0);
memset(&servAddr,0,sizeof(servAddr));
servAddr.sin_family = AF_INET;
servAddr.sin_port = htons(PORT);
if (inet_pton(AF_INET,argv[1],&servAddr.sin_addr) <= 0)
{
sys_err("inet_pton error");
}
connect(sockFd,(struct sockaddr *)&servAddr,sizeof(servAddr));
while((n=read(sockFd,recvLine,MAXLINE)) >0 )
{
recvLine[n] = '\0';
if(fputs(recvLine,stdout) == EOF)
{
sys_err("fputs error");
}
}
if(n <0)
{
sys_err("read error");
}
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include "aes_options.h" //add
int main()
{
int len;
int client_sockfd;
struct sockaddr_in server_addr;
char buffer[BUFSIZ];
char *encrypt_string = NULL;
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
server_addr.sin_port = htons(9000);
if((client_sockfd = socket(PF_INET, SOCK_STREAM, 0)) < 0)
{
perror("socket create failed");
return 1;
}
int username;
int password;
printf("enter the username:");
scanf("%d", &username);
printf("enter the password:");
scanf("%d", &password);
if (username !=2020 || password != 1220)
{
printf("uncorrect name!\n");
return 1;
}
if(connect(client_sockfd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) < 0)
{
perror("connect failed");
return 1;
}
printf("connect to server\n");
len = recv(client_sockfd, buffer, BUFSIZ, 0);
buffer[len] = '\0';
printf("%s", buffer);
while(1)
{
printf("enter a data:");
scanf("%s", buffer);
if(!strcmp(buffer,"quit"))
break;
int encrypt_length = encrypt(buffer, &encrypt_string); //add
len = send(client_sockfd, encrypt_string, encrypt_length, 0); //add
len = recv(client_sockfd, buffer, BUFSIZ, 0);
buffer[len] = '\0';
printf("recived:%s \n", buffer);
}
close(client_sockfd);
printf("bye");
return 0;
}
/*char username;
int password;
printf("enter the username:");
scanf("%s", &username);
printf("enter the password:");
scanf("%d", &password);
if (username != "cdj" || password != 20201220)
{
printf("uncorrect name!\n");
return 1;
}
*/