一、网络
基础:
检查网络通不通: ping ip地址
ping 广播通不通: ping -b ip地址
查看网络配置信息: ifconfig -a
lsof(list open files)是一个列出当前系统打开文件的工具
netstat -tn
显示目前的路由表:route
概念:
网络通信采用socket模型,
网络通信本质也是进程间的Ipc。只是用在不同主机之间的通信
识别主机:4字节整数:ip地址
识别进程:2字节整数:端口号
IP地址的表示方法:内部表示:四字节整数(不方便记忆);外部表示:数点字符串表示;
struct sockaddr_in
{
int sin_family;
in_port_t sin_port;
struct in_addr sin_addr;
}
struct in_addr
{
in_addr_t s_addr;
}
IP地址的转换
inet_addr //把字符串转换为整数(网络)
inet_aton //把字符串转换为struct in_addr
inet_network //吧字符串转换为整数(本地)
inet_ntoa //吧结构体转换为字符串
、、、、、、、、、、、、、、、、、、、、、、、、、、、、
使用Tcp发送数据的时候:
1、不要以为固定长度的数据,一定接收成功,对于定长数据建议用MSG_WAITALL,确保可以保证按照固定长度填充满接收。
eg: send(serverfd,"hello",5,MSG_WAITALL);
2、对于字符串数据以及文件数据等不固定长度的数据的发送?
制定数据包:
头:头大小固定(放的是数据的大小);
体:体数据大小变化(放的数据);
头和体一起做成数据包;
例子:发送一个2M的文件,不可以一次发送完成,可能缓冲溢出等问题;应该分批次发送
每次可按照256字节发送。。。
1、长度+数据;
2、长度+数据;
。。。。
n、。。。。。
这种方法可以保证数据正确发送过去!
案例:
@ 使用Tcp传送文件,定义文件数据包:int (数据大小);char[] (数据);
@ 传递文件名,传递数据(循环),传递0长度的数据结束。
代码测试:###TCP,客户端发送文件中的数据
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <linux/un.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <fcntl.h>
int main()
{
int sfd;
int ffd;
int r;
int size;
struct sockaddr_in dr;
char filename[] = "a.txt";
char buf[128];
int len;
//socket
sfd = socket(AF_INET,SOCK_STREAM,0);
if(sfd == -1)printf("1:%m\n"),exit(-1);
printf("建立服务器socket成功\n");
//connect
dr.sin_family = AF_INET;
dr.sin_port = htons(9999);
inet_aton("10.25.2.101",&dr.sin_addr);
r = connect(sfd,(struct sockaddr*)&dr,sizeof(dr));
if(r == -1)printf("2:%m\n"),exit(-1);
printf("链接成功\n");
//打开文件
ffd = open(filename,O_RDONLY);
if(ffd == -1)printf("3:%m\n"),exit(-1);
printf("打开OPEN文件成功!\n");
//发送文件名
len = strlen(filename);
r = send(sfd,&len,sizeof(len),0);
if(r == -1)printf("4:%m\n"),exit(-1);
send(sfd,filename,len,0);
printf("发送成功!\n");
//循环发送数据
while(1)
{
size = read(ffd,buf,128);
if(size == -1)break;
if(size == 0) break;
if(size > 0)
{
send(sfd,&size,sizeof(size),0);//先发送数据的长度
r = send(sfd,buf,size,0);//再发送数据
if(r==-1)
{
printf("shibai");
break;
}
}
}
//读取到文件尾,发送0数据包
r = 0;
send(sfd,&r,sizeof(r),0);
close(ffd);
close(sfd);
printf("发送成功!\n");
}
代码测试:###TCP,服务器端接收文件中的数据
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <linux/un.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <fcntl.h>
int main()
{
int sfd,ffd;
int cfd;
int r;
char filename[100];
struct sockaddr_in dr;
int len;
char buf[128];
//socket
sfd = socket(AF_INET,SOCK_STREAM,0);
if(sfd == -1)printf("1:%m\n"),exit(-1);
printf("建立服务器socket成功\n");
//bind IP和端口
dr.sin_family = AF_INET;
dr.sin_port = htons(9999);
dr.sin_addr.s_addr = inet_addr("10.25.2.101");
r = bind(sfd,(struct sockaddr*)&dr,sizeof(dr));
if(r == -1)printf("2:%m\n"),exit(-1);
printf("地址绑定成功\n");
//listen
r = listen(sfd,10);
if(r == -1)printf("3:%m\n"),exit(-1);
printf("监听服务器成功\n");
//accept
cfd = accept(sfd,0,0);
if(r == -1)printf("4:%m\n"),exit(-1);
printf("开始接收文件\n");
//接收文件名
r = recv(cfd,&len,sizeof(len),MSG_WAITALL);
r = recv(cfd,filename,len,MSG_WAITALL);
filename[len] = 0;
printf("传递的文件名:%s\n",filename);
//创建文件
ffd = open(filename,O_RDWR|O_CREAT,0666);
//循环接受
while(1)
{
r = recv(cfd,&len,sizeof(len),MSG_WAITALL);
r = recv(cfd,buf,len,MSG_WAITALL);
if(r ==0)
break;
write(ffd,buf,len);
printf("%s\n",buf);
}
//关闭fd;
close(ffd);
close(cfd);
close(sfd);
}