网络基础
进程间通信与socket编程的区别
1、进程间通信,是在同一台电脑上同信
2、socket网络编程,同一局域网
ipv4、ipv6:
ipv4:占32位,容纳主机数为 2^32-1
ipv6 :占128位,容纳主机数 2^128-1
网络分类:
1、A类 0 000 0000 ——0 111 1111
2、B类 10 00 0000 ——10 11 1111
3、C类 110 0 0000——110 1 1111
4、D类 1110 0000 ——-1110 1111
5.保留地址
子网掩码
网络号全1 ,主机号全0;掩掉主机号,得到网络地址
作用:判断各个ip地址是否处于同一网段
子网划分:
利用主机号进行划分成网络
作用:将同一网段的网络划分成多个组,便于管理网络
判断:划分过子网,子网掩码不是整数
tcp&&udp
tcp:传输控制协议
udp:用户数据包协议
三次握手协议与四次挥手协议
1、请求连接
2、应答,并发送自己的序列号
3、应答建立连接
声明:每次发送时,都会发送syn和确认号;每次发送syn+1,作为对消息的回复
四次挥手
1、A对B说,咱们分手吧!
2、B答应
3、B说咱们分手吧!
4、A答应
socket编程
TCP
声明:
1、服务端:创建套接字——绑定服务器的端口和IP——监听客户端阻塞队列——接受连接,返回通信套接字——收发数据——关闭套接字
2、客户端:创建套接字——绑定服务器的端口和ip ——收发数据——关闭套接字
3、监听队列和Accept配合使用,每次获取一个客户端进行与服务器的接收连接工作
4、要实现一个服务器和客户端进行多句通信,创建多进程,一个进程用于写数据,一个进程用于读数据;同理线程也可以
5、要实现服务器与多个客户端通信,则修改Accept函数,循环创建多个通信套接字,这个套接字用于和客户端的通信(客户端不同,分配的套接字不同)
6、使用send()和recv()进行收发数据
实现:
//utili.h //包裹函数
#include<stdio.h>
#include<string.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/socket.h>
#include<netinet/in.h>
//服务器的端口 和 ip
#define SER_PORT 9090
#define SER_IP "10.0.2.15"
//定义连接请求队列长度
#define LISTEN_NUM 12
//缓存区大小
#define BUFFER 256
////////////////////////////////
//创建socket
int Socket(int domain,int type,int protocol)
{
int sockSer=socket(domain,type,protocol);
if(sockSer == -1)
{
perror("socket");
}
return sockSer;
}
//绑定服务器
int Bind(int socket,const struct sockaddr *address,socklen_t address_len)
{
int ret = bind(socket,address,address_len);
if(ret == -1)
{
perror("bind");
}
return 0;
}
//监听客户端队列
int Listen(int socket,int backlog)
{
int res = listen(socket,backlog);
if(res == -1)
{
perror("listen queue");
}
return 0;
}
//接收客户端的连接请求
int Accept(int socket,struct sockaddr *address,socklen_t * address_len)
{
int connfd = accept(socket,address,address_len);
if(connfd == -1)
{
perror("connfd");
}
return connfd;
}
//客户端连接服务器
int Connect(int socket,struct sockaddr *addr,socklen_t address)
{
int res = connect(socket,addr,address);
if(res == -1)
{
printf("Cli Connect Ser Fail\n");
exit(1);
}
else
{
printf("Cli Connect Ser Success.\n");
}
}
///////////////////////////////
//ser.c
#include"../utili.h"
int main()
{
//填充地址家族
struct sockaddr_in ser_addr,cli_addr;
ser_addr.sin_family = AF_INET;
ser_addr.sin_port = htons(SER_PORT);
ser_addr.sin_addr.s_addr =inet_addr(SER_IP);
//创建
int sockSer = Socket(AF_INET,SOCK_STREAM,0);
//printf("sockSer = %d\n",sockSer);
int option_val = 1;
//设置地址重用
setsockopt(sockSer,SOL_SOCKET,SO_REUSEADDR,&option_val,sizeof(option_val));
socklen_t ser_len =sizeof(struct sockaddr_in);
//绑定服务器
int ret = Bind(sockSer,(struct sockaddr*)&ser_addr,ser_len);
//printf("ret = %d\n",ret);
//监听队列
int res = Listen(sockSer,LISTEN_NUM);
//printf("res = %d\n",res);
socklen_t cli_len = sizeof(struct sockaddr_in);
//接收,返回通信套接字
int connfd =Accept(sockSer,(struct sockaddr*)&cli_addr,&cli_len);
char send_buffer[BUFFER];
char recv_buffer[BUFFER];
while(1)
{
//收数据
recv(connfd,recv_buffer,BUFFER,0);
printf("Cli>%s\n",recv_buffer);
//发数据
printf("Ser>");
scanf("%s",send_buffer);
if(!strcmp(send_buffer,"quit"))
{
break;
}
send(connfd,send_buffer,strlen(send_buffer)+1,0);
}
//关闭socket套接字
close(sockSer);
return 0;
}
//cli.c
#include"../utili.h"
int main()
{
//填充地址家族
struct sockaddr_in ser_addr;
ser_addr.sin_family = AF_INET;
ser_addr.sin_port = htons(SER_PORT);
ser_addr.sin_addr.s_addr = inet_addr(SER_IP);
socklen_t sock_len = sizeof(struct sockaddr);
//创建socket
int sockCli = Socket(AF_INET,SOCK_STREAM,0);
printf("sockCli = %d\n",sockCli);
//客户端连接服务器
int res = Connect(sockCli,(struct sockaddr*)&ser_addr,sock_len);
char send_buffer[BUFFER];
char recv_buffer[BUFFER];
while(1)
{
//发数据
printf("Cli>");
scanf("%s",send_buffer);
if(!strcmp(send_buffer,"quit"))
{
break;
}
send(sockCli,send_buffer,strlen(send_buffer)+1,0);
//收数据
recv(sockCli,recv_buffer,BUFFER,0);
printf("Ser>%s\n",recv_buffer);
}
//关闭套接字
close(sockCli);
}
//Makefile
all: ser cli
ser :
gcc -o ser ser.c
cli:
gcc -o cli cli.c
clean
rm ser cli
UDP
声明
1、服务器:创建socket——绑定服务器的端口和IP——收发数据——关闭套接字
2、客户端:创建socket——收发数据——关闭套接字
3、客户端要填充服务器的端口和ip
4、使用sendto()和recvfrom()函数,进行发送和接受数据。
//ser.c
#include"utili.h"
int main()
{
//填充服务端地址家族
struct sockaddr_in ser_addr,cli_addr;
ser_addr.sin_family = AF_INET;
ser_addr.sin_port = htons(SER_PORT);
ser_addr.sin_addr.s_addr = inet_addr(SER_IP );
// 获取socket
int sockSer = Socket(AF_INET,SOCK_DGRAM,0);
socklen_t sock_len = sizeof(struct sockaddr);
//绑定服务端
int res = Bind(sockSer,(struct sockaddr *)&ser_addr,sock_len);
char send_buffer[BUFFER_SIZE];
char recv_buffer[BUFFER_SIZE];
//收发数据
while(1)
{
recvfrom(sockSer,recv_buffer,BUFFER_SIZE,0,( struct sockaddr*)&cli_addr,&sock_len);
printf("Cli>%s\n",recv_buffer);
printf("Ser>");
scanf("%s",send_buffer);
sendto(sockSer,send_buffer,strl0,(const struct sockaddr*)&cli_addr,sock_len);
}
clen);
}
//关闭套接字
close(sockSer);
}
return 0;
}
//cli.c
#include"utili.h"
int main()
{
struct sockaddr_in ser_addr, cli_addr;
ser_addr.sin_family = AF_INET;
ser_addr.sin_port = htons(SER_PORT);
ser_addr.sin_addr.s_addr = inet_addr(SER_IP);
int sock_cli = Socket(AF_INET,SOCK_DGRAM,0);
char send_buffer[BUFFER_SIZE];
char recv_buffer[BUFFER_SIZE];
socklen_t sock_len = sizeof(struct sockaddr);
while(1)
{
printf("Cli>");
scanf("%s",send_buffer);
sendto(sock_cli,send_buffer,strlen(send_buffer)+1,0,(const struct sockaddr*)&ser_addr,sock_len);
recvfrom(sock_cli,recv_buffer,BUFFER_SIZE,0,(struct sockaddr *)&ser_addr,&sock_len);
printf("Ser>%s\n",recv_buffer);
}
//关闭套接字
close(sockCli);
}
return 0;
}
//Makefile
all:ser cli
ser:
gcc -o ser ser.c
cli:
gcc -o cli cli.c
clean:
rm ser cli