linux-基础-网络
来源:互联网 发布:51hei单片机论坛 编辑:程序博客网 时间:2024/06/15 08:16
大纲:
1.linux网络概述
2.网络编程基础
3.网络编程实例
一.linux网络概述
1.linux优势
1)完善内置网络
2)提供大量支持internet的免费软件
3)用户可以通过linux命令来完成内部信息和文件传输
4)远程访问
5)安全可靠
2.linux网络模型—–TCP/IP4层
应用层(telnet,文件传输协议–ftp,tftp,smtp,dns)
传输层(传输控制协议–TCP,用户数据报文协议–UDP)
网络层(internet协议–IP,网络控制报文协议–ICMP和地址解析协议–ARP)
网络接口层
二.网络编程的基础
1.linux网络编程通过socket实现,socket是一种文件描述符
socket有三种类型
1)流式套接字(TCP/IP协议)(SOCK_STREAM)
2)数据报套接字(SOCK_DGRAM)使用UDP协议
3)原始套接字(SOCK_RAW)使用IP协议,用于新网络协议测试
2.在socket程序中,struct sockaddr用于记录网络地址
struct sockaddr{
u_short sa_family; //协议族,采用”AF_xxx”,如AF_INET(IP协议族)
char sa_data[14]; //14字节的特定协议地址
};
3.在socket程序设计中,struct socketaddr_in同样用于记录网络地址
struct sockaddr_in {
short int sin_family; /* 地址族 */
unsigned short int sin_port; /* 端口号 */
struct in_addr sin_addr; /* 协议特定地址 */
unsigned char sin_zero[8]; /* 填0 */
};
struct in_addr
struct in_addr {
unsigned long s_addr;
};
或者
typedef struct in_addr{
union{
struct{
unsigned char s_b1,s_b2,s_b3,s_b4;
} S_un_b;
struct{
unsigned short s_w1,s_w2;
} S_un_w;
unsigned long S_addr;//成员s_addr为长整形结构
} S_un;
}IN_ADDR;
编程中一般使用sockaddr等价于sockaddr_in数据结构
通常IP形式是192.168.0.29,在struct in_addr的ip为32位整数
使用函数转化
int inet_aton(const char*cp,struct in_addr *inp)
char *inet_ntoa(struct in_addr in)
a表示ascii码,n表示network
inet_aton—-将a.b.c.d形式转为32位ip形式存储在inp指针里面
inet_ntoa—-将32位ip转为a.b.c.d
4.字节转换
网络字节传输顺序(big endian)
htons(unsigned short–>网络序)
ntons(网络序–>主机序)
htonl(unsigned long–>网络序)
ntonl(网络序–>主机序)
5.在网络中标识一台主机可以是ip地址,也可以是主机名
stuct hostent *gethostbyname(const char *hostname)
这个函数的传入值是域名或者主机名,例如”www.baidu.com”等等。
传出值,是一个hostent的结构。如果函数调用失败,将返回NULL。
需要包含的头文件
#include <netdb.h>#include <sys/socket.h>
返回值hostent结构体指针
struct hostent
{
char *h_name; //主机名
char **h_aliases;//主机别名
int h_addrtype;//主机地址类型AF_INET
int h_length;//主机地址长度
char **h_addr_list;//主机IP地址列表
#define h_addr h_addr_list[0]//主机第一个IP地址
};
6.socket编程步骤
1)socket创建
int socket(int protofamily, int type, int protocol);//返回sockfd-描述符
protofamily:协议族(family)。常用的协议族有,AF_INET(IPV4)、AF_INET6(IPV6)、AF_LOCAL(或称AF_UNIX,Unix域socket)、AF_ROUTE等等。协议族决定了socket的地址类型,在通信中必须采用对应的地址
type:指定socket类型。
常用的socket类型有:
SOCK_STREAM、SOCK_DGRAM、SOCK_RAW、SOCK_PACKET、SOCK_SEQPACKET等等
protocol:指定协议。
常用的协议有:IPPROTO_TCP、IPPTOTO_UDP、IPPROTO_SCTP、IPPROTO_TIPC等,它们分别对应TCP传输协议、UDP传输协议、STCP传输协议、TIPC传输协议
SOCK_STREAM不可以跟IPPROTO_UDP组合。当protocol为0时,会自动选择type类型对应的默认协议。
2)bind绑定ip和端口号到socket
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
sockfd:socket描述字,它是通过socket()函数创建
addr:一个const struct sockaddr *指针,指向要绑定给sockfd的协议地址,根据地址协议不同创建函数也不同struct sockaddr_in
addrlen:对应的是地址的长度
3)connect与服务器建立连接
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
4)listen设置服务器最大连接数
int listen(int sockfd, int backlog);
5)accpet等待客户端socket连接请求
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen); //返回连接connect_fd
6)send发送数据
7)recv接收数据
7.基于TCP程序设计步骤
a.服务器端
1)创建一个socket,用socket()
2)绑定IP地址,端口信息到socket,bind()
3)设置最大允许连接数listen()
4)等待客户端请求accept()
5)发送数据send(),recv()或者read(),write()
6)关闭网络连接
b.客户端
1)创建一个socket,用socket()
2)绑定IP地址,端口信息到socket,bind()
3)连接服务器connect()
4)发送数据send(),recv()或者read(),write()
read(),write()这些函数在之前IO口文件操作的章节已经介绍过啦
5)关闭网络连接
8.基于UDP程序设计步骤
a.服务器端
1)创建一个socket,用socket()
2)绑定IP地址,端口信息到socket,bind()
3)循环接收数据recvfrom()
4)关闭网络连接
int close(int fd);
b.客户端
1)创建一个socket,用socket()
2)绑定IP地址,端口信息到socket,bind()
3)设置对方的ip地址和端口信息
4)发送数据sendto()
5)关闭网络连接
三.网络编程实例
客户端
#include<stdio.h> #include<stdlib.h> #include<string.h> #include<errno.h> #include<sys/types.h>#include<sys/socket.h> #include<netinet/in.h> #define portnumber 3333int main(int argc,char *argv[]){int sockfd;char buffer[1024];struct sockaddr_in server_addr;struct hostent *host;if(argc!=2){ fprintf(stderr,"usage:%s hostname\n",argv[0]); exit(1); }/*if(host=gethostbyname(argv[1])==NULL){//获取主机名 fprintf(stderr,"get hostname error\n"); exit(1); }*/if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1){//创建socket fprintf(stderr,"socket error:%s\n",strerror(errno)); exit(1); }bzero(&server_addr,sizeof(server_addr));/*void _bzero (void *s, size_t len);将s的前len字节设为0==>这里是把server_addr内存地址清空*,和memset一样*/ server_addr.sin_family=AF_INET;//地址簇 server_addr.sin_port=htons(portnumber);//端口号// server_addr.sin_addr.s_addr=inet_addr("127.0.0.1");// server_addr.sin_addr=*((struct in_addr*)host->h_addr);//协议特定地址#if 1if(inet_pton(AF_INET,argv[1],&server_addr.sin_addr)<=0){ printf("inet_pton error for %s\n",argv[1]); exit(1); }#endifif (connect(sockfd,(struct sockaddr*)(&server_addr),sizeof(struct sockaddr_in))==-1){//连接服务器 perror("connect error"); exit(1); }printf("connect success\n");fgets(buffer,1024,stdin);//stdin--标准输入流,就是键盘,读一行字符串(长度 <= 1024),包括换行键,存入bufferwrite(sockfd,buffer,strlen(buffer));//将strlen(buffer)个字节长度的数据从buffer读到文件描述符sockfd中close(sockfd);//关闭网络连接exit(0);}
服务器端
#include<stdio.h> #include<stdlib.h> #include<string.h> #include<errno.h> #include<sys/types.h>#include<sys/socket.h> #include<netinet/in.h> #define portnumber 3333int main(int argc,char *argv[]){ int sockfd,new_fd; struct sockaddr_in server_addr; struct sockaddr_in client_addr; int sin_size; int nbytes; char buffer[1024]; if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1){//创建socket fprintf(stderr,"socket error:%s\n",strerror(errno)); exit(1); } bzero(&server_addr,sizeof(server_addr)); server_addr.sin_family=AF_INET;//地址簇 server_addr.sin_addr.s_addr=htonl(INADDR_ANY);//IP地址设置成INADDR_ANY,让系统自动获取本机的IP地址。 server_addr.sin_port=htons(portnumber);//端口号 if(bind(sockfd,(struct sockaddr*)(&server_addr),sizeof(struct sockaddr_in))==-1){ printf("bind error:%s\n",strerror(errno)); exit(1); } if(listen(sockfd,5)==-1){ printf("listen error\n"); exit(1); }printf("=======wait=========\n"); while(1){ sin_size=sizeof(struct sockaddr_in); if((new_fd=accept(sockfd,(struct sockaddr*)(&client_addr),(socklen_t*)&sin_size))==-1){ printf("accept error\n"); exit(1); } printf("accept success\n"); if((nbytes=read(new_fd,buffer,1024))==-1){ printf("read error\n"); exit(1); } buffer[nbytes]='\0'; printf("success\n"); close(new_fd);}
测试结果
- linux网络配置基础
- Linux网络基础
- Linux网络基础
- linux网络基础
- Linux网络基础
- linux网络编程基础
- Linux 网络配置基础
- Linux 网络编程基础
- linux网络基础命令
- Linux网络基础
- Linux网络编程基础
- Linux网络基础
- Linux网络编程基础
- linux 网络编程基础
- Linux基础网络知识
- Linux网络编程基础
- Linux网络基础配置
- Linux网络基础配置
- intellij idea 添加jar包
- 链表编程题专题--逆序链表
- clion安装配置
- ADB
- while(cin && cin.get() != '\n') continue;
- linux-基础-网络
- 程序员实现财务自由的9个阶段,你达到了哪一段?
- 三星高级工程师演讲 | 企业级SSD发展趋势
- 前端市场要求
- jQuery操作组件
- 运维
- 关键字final和abstract是否可以同时做类的修饰符,为什么?
- java 调度工具之 Quartz
- JavaScript eval() 函数