文章参考链接:
————————————————
版权声明:本文为CSDN博主「杰儿__er」的原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_42167759/article/details/81255812
Socket概述
① 所谓Socket通常也称作“套接字”,用于描述IP地址和端口,是一个通信链的句柄。应用程序通常通过“套接字”向网络发出请求或者应答网络请求。
② Socket是连接运行在网络上的两个程序间的双向通信的端点。
③ 网络通讯其实指的就是Socket间的通讯。
④ 通讯的两端都有Socket,数据在两个Socket之间通过IO来进行传输。
套接字socket的类型
(1)流式套接字(SOCK_STREAM)
提供面向连接、可靠的数据传输服务,数据无差错、无重复的发送,且按发送顺序接收(TCP协议)
(2)数据报式套接字(SOCK_DGRAM)
提供无连接服务,数据包以独立包形式发送,不提供无措保证,数据可能丢失,并且接收顺序混乱(UDP协议)
(3)原始套接字(SOCK_RAM)
套接字(socket)
socket起源于Unix,而Unix/Linux基本哲学之一就是“一切皆文件”,都可以用“打开open –> 读写write/read –> 关闭close”模式来操作。Socket就是该模式的一个实现,socket即是一种特殊的文件,一些socket函数就是对其进行的操作(读/写IO、打开、关闭).说白了Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。
随着Unix的应用推广,套接字有被引进了windows等操作系统。套接字通常只与同一区域的套接字交换数据,windows socket只支持一个通信区域:网际域(AF_INET),这个域被使用忘记协议簇的通信进程使用。
使用Socket进行网络通信的过程
① 服务器程序将一个套接字绑定到一个特定的端口,并通过此套接字等待和监听客户的连接请求。
② 客户程序根据服务器程序所在的主机和端口号发出连接请求。
③ 如果一切正常,服务器接受连接请求。并获得一个新的绑定到不同端口地址的套接字。
④ 客户和服务器通过读、写套接字进行通讯。
客户机/服务器模式
在TCP/IP网络应用中,通信的两个进程间相互作用的主要模式是客户机/服务器模式*(client/server),即客户像服务其提出请求,服务器接受到请求后,提供相应的服务。
服务器:
(1)首先服务器方要先启动,打开一个通信通道并告知本机,它愿意在某一地址和端口上接收客户请求
(2)等待客户请求到达该端口
(3)接收服务请求,处理该客户请求,服务完成后,关闭此新进程与客户的通信链路,并终止
(4)返回第二步,等待另一个客户请求
(5)关闭服务器
客户方:
(1)打开一个通信通道,并连接到服务器所在的主机特定的端口
(2)向服务器发送请求,等待并接收应答,继续提出请求
(3)请求结束后关闭通信信道并终止
环境是linux
基于TCP(面向连接)的socket编程
study
流式传输:“客户端”,1.socket()函数;2.bind()函数可有可无,加上指定传输端口,不加随机分配端口;3.connect()函数,填写服务端的地址与端口【网络间通信AF_STREAM】或者路径【进程间通信AF_DGRAM】;4.send()函数;5.recv()函数。
流式传输:“服务端”,1.socket()函数;2.bind()函数,必须加上指定传输端口【网络间通信AF_STREAM】或者是路径【进程间通信AF_DGRAM】 ;3.listen()函数,使用isockfd;5.accepc()函数,生成新的fd,inewfd;6.send()函数,inewfd;7.recv()函数,inewfd。
服务器端先初始化Socket,然后与端口绑定(bind),对端口进行监听(listen),调用accept阻塞,等待客户端连接。在这时如果有个客户端初始化一个Socket,然后连接服务器(connect),如果连接成功,这时客户端与服务器端的连接就建立了。客户端发送数据请求,服务器端接收请求并处理请求,然后把回应数据发送给客户端,客户端读取数据,最后关闭连接,一次交互结束。
基于TCP(面向连接)的socket编程——流式套接字(SOCK_STREAM)
网络间通信AF_INET,典型的TCP/IP四型模型的通信过程
服务器:
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#define SERVER_PORT 6666
/*
* 监听后,一直处于accept阻塞状态,
* 直到有客户端连接,
* 当客户端如数quit后,断开与客户端的连接
* */
int main()
{
//调用socket函数返回的文件描述符
//
int serverSocket;
//
// //声明两个套接字sockaddr_in结构体变量,分别表示客户端和服务器
//
struct sockaddr_in server_addr;
struct sockaddr_in clientAddr;
int addr_len = sizeof(clientAddr);
int client;
char buffer[200];
int iDataNum;
//socket函数,失败返回-1
//int socket(int domain, int type, int protocol);
//第一个参数表示使用的地址类型,一般都是ipv4,AF_INET
//第二个参数表示套接字类型:tcp:面向连接的稳定数据传输SOCK_STREAM
//第三个参数设置为0
if((serverSocket = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
perror("socket");
//perror(s) 用来将上一个函数发生错误的原因输出到标准设备(stderr)。参数 s 所指的字符串会先打印
//出,后面再加上错误原因字符串。此错误原因依照全局变量errno的值来决定要输出的字符串。
return 1;
}
bzero(&server_addr, sizeof(server_addr));
//初始化服务器端的套接字,并用htons和htonl将端口和地址转成网络字节序
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(SERVER_PORT);
//ip可是是本服务器的ip,也可以用宏INADDR_ANY代替,代表0.0.0.0,表明所有地址
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
//对于bind,accept之类的函数,里面套接字参数都是需要强制转换成(struct sockaddr *)
// bind三个参数:服务器端的套接字的文件描述符,
if(bind(serverSocket, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
perror("connect");
return 1;
}
//设置服务器上的socket为监听状态
if(listen(serverSocket,5)<0) {
perror("listen");
return 1;
}
while(1) {
printf("监听端口: %d\n", SERVER_PORT);
调用accept函数后,会进入阻塞状态
//accept返回一个套接字的文件描述符,这样服务器端便有两个套接字的文件描述符,
// serverSocket和client。
//erverSocket仍然继续在监听状态,client则负责接收和发送数据
//clientAddr是一个传出参数,accept返回时,传出客户端的地址和端口号
//addr_len是一个传入-传出参数,传入的是调用者提供的缓冲区的clientAddr的长度,以避免缓冲区溢出。
//传出的是客户端地址结构体的实际长度。
//出错返回-1
client = accept(serverSocket, (struct sockaddr*)&clientAddr, (socklen_t*)&addr_len);
if(client < 0) {
perror("accept");
//用来将上一个函数发生错误的原因输出到标准设备(stderr)
continue;
}
printf("等待消息...\n");
//inet_ntoa ip地址转换函数,将网络字节序IP转换为点分十进制IP
//表达式:char *inet_ntoa (struct in_addr);
printf("IP is %s\n", inet_ntoa(clientAddr.sin_addr));
printf("Port is %d\n", htons(clientAddr.sin_port));
while(1) {
printf("读取消息:");
buffer[0] = '\0';
iDataNum = recv(client, buffer, 1024, 0);
if(iDataNum < 0) {
perror("recv null");
continue;
}
buffer[iDataNum] = '\0';
if(strcmp(buffer, "quit") == 0)
break;
printf("%s\n", buffer);
printf("发送消息:");
scanf("%s", buffer);
printf("\n");
send(client, buffer, strlen(buffer), 0);
if(strcmp(buffer, "quit") == 0)
break;
}
}
close(serverSocket);
return 0;
}
客户端:
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#define SERVER_PORT 6666
/*
* 连接到服务器后,会不停循环,等待输入,
* 输入quit后,断开与服务器的连接
* */
int main()
{
//客户端只需要一个套接字文件描述符,用于和服务器通信
int clientSocket;
//描述服务器的socket
struct sockaddr_in serverAddr;
char sendbuf[200];
char recvbuf[200];
int iDataNum;
if((clientSocket = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
perror("socket");
return 1;
}
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(SERVER_PORT);
//指定服务器端的ip,本地测试:127.0.0.1
//inet_addr()函数,将点分十进制IP转换成网络字节序IP
serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
if(connect(clientSocket, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) < 0) {
perror("connect");
return 1;
}
printf("连接到主机...\n");
while(1) {
printf("发送消息:");
scanf("%s", sendbuf);
printf("\n");
send(clientSocket, sendbuf, strlen(sendbuf), 0);
if(strcmp(sendbuf, "quit") == 0)
break;
printf("读取消息:");
recvbuf[0] = '\0';
iDataNum = recv(clientSocket, recvbuf, 200, 0);
recvbuf[iDataNum] = '\0';
printf("%s\n", recvbuf);
}
close(clientSocket);
return 0;
}
一、SMTP协议(C语言实现发送文件)
二、正则表达式
三、了解cookie
两种方式快速查看当前网页COOKIE
1.在浏览器的地址栏输入:javascript:alert(document.cookie) (不区分大小写),就会弹出你在当前网页登录的cookie信息。
注意:你把以上复制进入地址栏后会发现,“javascript”字符串消失不见,不管“javascript”里面哪一个字母被大写或小写,只要识别为“javascript”就会自动被过滤隐藏消失。
你应该复制下面这个到地址栏(粘贴到地址栏后再把前面的“1”去掉):
1javascript:alert(document.cookie)
2.按F12进入浏览器的开发者模式——console——在命令行输入javascript:alert(document.cookie),再回车
第一点:每个网站的cookie信息相互独立; 第二点:cookie信息是随着服务器端返回的头信息来设置;
cookie是做什么的?参考如下
版权声明:本文为CSDN博主「Captainxby」的原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/chuan_zhang_ak/article/details/52077151
Cookie最早是网景公司的前雇员Lou Montulli在1993年3月的发明。
Cookie是由服务器端生成,发送给User-Agent(一般是浏览器),浏览器会将Cookie的key/value保存到某个目录下的文本文件内,下次请求同一网站时就发送该Cookie给服务器(前提是浏览器设置为启用cookie)。Cookie名称和值可以由服务器端开发自己定义,对于JSP而言也可以直接写入jsessionid,这样服务器可以知道该用户是否合法用户以及是否需要重新登录等。
也就是说:
当你在浏览网站的时候,Web服务器会先送一小段资料放在你的计算机上,Cookie 会帮你把在网页上所输入的文字或是一些选择,都记录下来。当下次你再光临同一个网站,Web服务器会先看看有没有它上次留下的Cookie资料,有的话,就会依据Cookie里的内容来判断使用者,送出特定的网页内容给你。
1、Cookie是什么?
它是一个数据包,每次访问网站的时候浏览器都会将该网站的Cookie发回给网站服务器,同时网站也可以随意更改你机器上对应的Cookie。Cookie不是只有一个,而是一个网站一个,所以把它比喻成网络身份证的说法是不准确的。它不是你在网络中的唯一标识,只是你在某个网站的唯一标识。
2、Cookie中都有什么东西?
事实上:普通网站都不会存重要的信息,它们仅仅存一个你的登陆状态,也就是你拿用户名密码换取的令牌,还有就是网站针对你的判定(比如你在这个网站上的唯一标识是什么,你访问的是我们的哪台服务器,你使用的是我们的哪个版本的产品),这些信息你都不需要关心,它和你的隐私一点关系都没有。
文艺一点的网站会将这些信息进行加密,目的是防止别人伪造这些信息欺骗网站。
3、Cookie会被人窃取吗?
Cookie只能被放置它的网站读取。这一点是浏览器保证的,这也是浏览器的一个重要的安全机制。这么说Cookie是安全的了?也不一定,Cookie在传输过程中和网站方都有可能被窃取。我举个不太恰当的例子:
我们可以把用户访问网站的过程比做你给网站写一封信,信的内容可以比做你提交给网站的一些信息(比如你的性别啊,年龄啊),Cookie可以比做信封中的寄信人,标识你是谁。那么在整个寄信过程中,邮电局是完全有机会窃取你的信封的,而网站也可以将你的信封卖给别人。但是!!!这两方其实已经拥有了你这封信的内容了,你觉得他们有必要偷你的信封吗?
事实上,Cookie的盗用一般在你使用了不安全的网络(比如公共场所的WiFi),或者网站出现安全漏洞的情况下才会放生,前者发生的概率就比较低,而后者对网站造成的影响远比Cookie被盗这点小事大很多,在互联网公司是严重的故障,一经发现很快就会堵上的。