socket网络编程(学习笔记)

文章参考链接:

 ———————————————— 
版权声明:本文为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被盗这点小事大很多,在互联网公司是严重的故障,一经发现很快就会堵上的。

 

4、安全问题?

Cookie会在登录的电脑中记录你登录过的信息网站状态, 所以在别人电脑上登录,公用电脑登录,或自己电脑让别人用都会出现安全问题。

 

生存周期

Cookie可以保持登录信息到用户下次与服务器的会话,换句话说,下次访问同一网站时,用户会发现不必输入用户名和密码就已经登录了(当然,不排除用户手工删除Cookie)。而还有一些Cookie在用户退出会话的时候就被删除了,这样可以有效保护个人隐私。

Cookie在生成时就会被指定一个Expire值,这就是Cookie的生存周期,在这个周期内Cookie有效,超出周期Cookie就会被清除。有些页面将Cookie的生存周期设置为“0”或负值,这样在关闭页面时,就马上清除Cookie,不会记录用户信息,更加安全。
 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

瓜洲大大

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值