粘包,Telnet,SSH,Wireshark

一,粘包

原因:tcp为流式套接字,数据与数据间没有边界,导致多次数据粘到一起。

解决:

1.规定一些数据间的间隔符,"\aa","\r\n";

2.可以指定要发送对象的数据长度。

3.自己将数据打包。

1.上传接收粘连

1.用户端

cpp 复制代码
#include <head.h>


int connect_server(const char *ip,const char *port)
{
	int fd = socket(AF_INET,SOCK_STREAM,0);
	if (fd < 0)
		handle_error_ret("socket fail");

	struct sockaddr_in seraddr;
	memset(&seraddr,0,sizeof(seraddr));

	seraddr.sin_family = AF_INET;
	seraddr.sin_addr.s_addr = inet_addr(ip);
	seraddr.sin_port = htons(atoi(port));//"50000"  

	if (connect(fd,(const struct sockaddr *)&seraddr,sizeof(seraddr)) < 0)
		handle_error_ret("connect_server fail");

	return fd;
}



//./cli 127.0.0.1 50000 filename 
int main(int argc, const char *argv[])
{
	if (argc != 4)
	{
		printf("usage: %s <ip> <port> <filename>\n",argv[0]);
		return -1;
	}

	int fd = connect_server(argv[1],argv[2]);
	if (fd < 0)
		return -1;
	
	int fd_s = open(argv[3],O_RDONLY);
	if (fd_s < 0)
		handle_error_ret("open fail");

	write(fd,argv[3],strlen(argv[3])+1);
//	write(fd,argv[3],strlen(argv[3]));

	char buf[100] = {0};
	int ret = 0;

	while (1)
	{
		ret = read(fd_s,buf,sizeof(buf));
		if (ret == 0)
			break;
		write(fd,buf,ret);
	}

	close(fd_s);
	close(fd);

	return 0;
}

2.服务器

cpp 复制代码
#include <head.h>


int init_server(const char *ip,const char *port)
{
	int fd = socket(AF_INET,SOCK_STREAM,0);
	if (fd < 0)
		handle_error_ret("socket fail");

	struct sockaddr_in seraddr;
	memset(&seraddr,0,sizeof(seraddr));

	seraddr.sin_family = AF_INET;
	seraddr.sin_addr.s_addr = inet_addr(ip);
	seraddr.sin_port = htons(atoi(port));//"50000"  

	if (bind(fd,(const struct sockaddr*)&seraddr,sizeof(seraddr)) < 0)
		handle_error_ret("bind fail");


	if (listen(fd,5) < 0)
	   handle_error_ret("listen fail");


	return fd;

}

//./ser 127.0.0.1 50000 
int main(int argc, const char *argv[])
{
    int ret = 0;
	if (argc != 3)
	{
		printf("Usage: %s <ip> <port>\n",argv[0]);
		return -1;
	}

	int listenfd = init_server(argv[1],argv[2]);

	if (listenfd < 0)
		return -1;


	int connfd = 0;

	if ((connfd = accept(listenfd,NULL,NULL)) < 0)
		handle_error_ret("accept fail");


	//读文件名 
	char buf[100] = {0};
	ret = read(connfd,buf,sizeof(buf));
	printf("ret = %d buf = %s\n",ret, buf);

	int fd_d = open(buf,O_WRONLY|O_CREAT|O_TRUNC,0666);
	if (fd_d < 0)
		handle_error_ret("open fail");

	while (1)
	{
		ret = read(connfd,buf,sizeof(buf));
		printf("ret = %d buf1 = %s \n",ret,buf);
		if (ret == 0)
		   break;
		write(fd_d,buf,ret);
	}

	close(fd_d);
	close(connfd);

	return 0;
}

3.注意

服务器和客户端不能写在同级别文件夹中

2.解决粘连

1.客户端

cpp 复制代码
#include <head.h>


int connect_server(const char *ip,const char *port)
{
	int fd = socket(AF_INET,SOCK_STREAM,0);
	if (fd < 0)
		handle_error_ret("socket fail");

	struct sockaddr_in seraddr;
	memset(&seraddr,0,sizeof(seraddr));

	seraddr.sin_family = AF_INET;
	seraddr.sin_addr.s_addr = inet_addr(ip);
	seraddr.sin_port = htons(atoi(port));//"50000"  

	if (connect(fd,(const struct sockaddr *)&seraddr,sizeof(seraddr)) < 0)
		handle_error_ret("connect_server fail");

	return fd;
}



//./cli 127.0.0.1 50000 filename 
int main(int argc, const char *argv[])
{
	if (argc != 4)
	{
		printf("usage: %s <ip> <port> <filename>\n",argv[0]);
		return -1;
	}

	int fd = connect_server(argv[1],argv[2]);
	if (fd < 0)
		return -1;
	
	int fd_s = open(argv[3],O_RDONLY);
	if (fd_s < 0)
		handle_error_ret("open fail");

	//write(fd,argv[3],strlen(argv[3])+1);
	write(fd,argv[3],strlen(argv[3]));

	//方式1 
	//sleep(1);


	//方式2 
	write(fd,"\r\n",2);


	char buf[100] = {0};
	int ret = 0;

	while (1)
	{
		ret = read(fd_s,buf,sizeof(buf));
		if (ret == 0)
			break;
		write(fd,buf,ret);
	}

	close(fd_s);
	close(fd);

	return 0;
}

2.服务器

cpp 复制代码
#include <head.h>


int init_server(const char *ip,const char *port)
{
	int fd = socket(AF_INET,SOCK_STREAM,0);
	if (fd < 0)
		handle_error_ret("socket fail");

	struct sockaddr_in seraddr;
	memset(&seraddr,0,sizeof(seraddr));

	seraddr.sin_family = AF_INET;
	seraddr.sin_addr.s_addr = inet_addr(ip);
	seraddr.sin_port = htons(atoi(port));//"50000"  

	if (bind(fd,(const struct sockaddr*)&seraddr,sizeof(seraddr)) < 0)
		handle_error_ret("bind fail");


	if (listen(fd,5) < 0)
	   handle_error_ret("listen fail");


	return fd;

}

//./ser 127.0.0.1 50000 
int main(int argc, const char *argv[])
{
    int ret = 0;
	if (argc != 3)
	{
		printf("Usage: %s <ip> <port>\n",argv[0]);
		return -1;
	}

	int listenfd = init_server(argv[1],argv[2]);

	if (listenfd < 0)
		return -1;


	int connfd = 0;

	if ((connfd = accept(listenfd,NULL,NULL)) < 0)
		handle_error_ret("accept fail");


	//读文件名 
	char buf[100] = {0};

	FILE *fp = fdopen(connfd,"r");
	if (fp == NULL)
		handle_error_ret("fdopen fail");


	fgets(buf,sizeof(buf),fp);  //buf => 1.txt\r\n
	buf[strlen(buf)-2] = '\0';

//	ret = read(connfd,buf,sizeof(buf));
//	printf("ret = %d buf = %s\n",ret, buf);

	printf("buf = %s\n",buf);
	int fd_d = open(buf,O_WRONLY|O_CREAT|O_TRUNC,0666);
	if (fd_d < 0)
		handle_error_ret("open fail");

	while (1)
	{
		//ret = read(connfd,buf,sizeof(buf));
		ret = fread(buf,1,sizeof(buf),fp);
		printf("ret = %d buf1 = %s \n",ret,buf);
		if (ret == 0)
		   break;
		write(fd_d,buf,ret);
	}

	close(fd_d);
	close(connfd);

	return 0;
}

3.recv send函数(仅用于TCP中)

1.recv 类似于read函数

用法

比read函数多一个参数,仅用于TCP中

2.send 类似于write函数

send recv函数最后一个参数即允许非阻塞操作。

二,telnet,SSH,wireshark

1.telent

1.在windows中

telent可以在windows上用cmd创建一个linux,需要在linux中用ifconfig查看ip地址即可

linux IP为 192.168.11.128

2.第三方软件

以他实例

选择Telnet,输入IP

2.SSH

功能与telnet类似,只是传输过程加密

3.wireshark 抓包工具 抓取网络上数据

1.抓取telnet

输入指令打开

红色输入蓝色输出

2.抓取SSH

加密了

三次招手与四次挥手

3.wireshark中的命令

相关推荐
Dream Algorithm16 分钟前
中国移动6周年!
网络·架构·信息与通信
小疆智控1 小时前
农田水利如何「聪明」起来?Modbus转Ethernet IP破解设备互联
网络·网络协议·tcp/ip
木mu升1 小时前
java 局域网 rtsp 取流 WebSocket 推送到前端显示 低延迟
网络·websocket·网络协议
Li-Yongjun3 小时前
深度解析 Linux 内核参数 net.ipv4.tcp_rmem:优化网络性能的关键
linux·网络·tcp/ip
枷锁—sha3 小时前
【DVWA系列】——xss(Reflected)——Medium详细教程
前端·网络·web安全·网络安全·xss
不像程序员的程序媛4 小时前
http接口莫名奇妙返回body空白
网络·网络协议·http
晴天¥4 小时前
第一章-数据通信网络基础
网络
XMAIPC_Robot5 小时前
RK3568/RK3588 KVM系统虚拟化解决方案
网络·fpga开发·边缘计算
IT葛大侠5 小时前
OSPF域内路由
运维·网络·计算机网络