互连网通讯技巧
分类:科技动态

网络通讯技术(NCT:Network Communication Technology)是指通过计算机和网络通讯设备对图形和文字等形式的资料进行采集、存储、处理和传输等,使信息资源达到充分共享的技术。通信网络技术

网络通信,网络通信协议

 

Socket:网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket。

图片 1

socket.png

server下的方法:bind() ,   listen(),  accept(),  recv(),   send(bytes(String)),   sendall(),    
client的方法:connect(),   recv(),    send(),  sendall()

通信网是一种由通信端点、节点和传输链路相互有机地连接起来,以实现在两个或更多的规定通信端点之间提供连接或非连接传输的通信体系。通信网按功能与用途不同,一般可分为物理网、业务网和支撑管理网等三种。

一 概述

网络通信要素
  • IP地址:网络上主机设备的唯一标识
  • 端口号:服务器上有不同的应用程序,用于标示进程的逻辑地址,不同进程的标示

### 建立通信的过程:创建socket,绑定ip和端口,监听,接收连接socket,用接受到的socket进行通讯。然后才能发送连接数据
server.py

物理网是由用户终端、交换系统、传输系统等通信设备所组成的实体结构,是通信网的物质基础,也称装备网。用户终端是通信网的外围设备,它将用户发送的各种形式的信息转变为电磁信号送入通信网路传送,或将从通信网路中接收到的电磁信号等转变为用户可识别的信息。用户终端按其功能不同,可分为电话终端、非话终端及多媒体通信终端。电话终端指普通电话机、移动电话机等;非话终端指电报终端,传真终端、计算机终端、数据终端等;多媒体通信终端指可提供至少包含两种类型信息媒体或功能的终端设备,如可视电话、电视会议系统等。交换系统是各种信息的集散中心,是实现信息交换的关键环节。传输系统是信息传递的通道,它将用户终端与交换系统之间以及交换系统相互之间联接起来,形成网路。传输系统按传输媒介的不同,可分为有线传输系统和无线传输系统两类。有线传输系统以电磁波沿某种有形媒质的传播来实现信号的传递。无线传输系统则是以电磁波在空中的传播来实现信号的传递。

1.网络模型

OSI(Open System Interconnection,开放式系统互联)模型,是对网络系统结构的概括,将网络分为七层:应用层、表示层、会话层、传输层、网络层、数据链路层、物理层。

传输协议
  • TCP:需要建立连接,传输数据大小不受限制,可靠协议、安全送达,效率低
    a、HTTP底层就是通过socket建立连接通信管道,实现数据传输
    b、HTTP是一个TCP的传输协议(方式),它是一个可靠,安全的协议
  • UDP:不需要建立连接,数据大小有限制,不可靠协议,传输速度快
    TCP/UDP是数据传输的方式,而HTTP/XMPP等一种数据传输的格式,为了方便接收和读取,你可以自己定义协议格式

网上看了小码哥的视频实现一个简单的聊天室,列下核心代码搞清楚中间发生了哪些事

//   服务端代码

#import "XMGServiceListener.h"
#import "GCDAsyncSocket.h"  // 基于Scoket原生的框架 CocoaAsyncSocket github上有下

@interface XMGServiceListener()<GCDAsyncSocketDelegate>
@property (nonatomic, strong) GCDAsyncSocket *serverSocket;   /** 服务端的socket */
@property (nonatomic, strong) NSMutableArray *clientSockets;  //客户端的所有socket对象
@end


@implementation XMGServiceListener

-(void)start{  // 开启服务端
    // 1.创建一个socket对象
    // serverSocket 服务端的socket只监听 有没有客户端请求连接
    GCDAsyncSocket *serverSocket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_global_queue(0, 0)];

    // 2.绑定端口,并开启监听,代表服务端已经开启  端口号使用1024以上的 0-1024为系统端口
    NSError *error = nil;
    [serverSocket acceptOnPort:5288 error:&error];
    if (!error) {
        NSLog(@"服务开启成功");
    }else{
        //失败原因是端口被其它程序占用
        NSLog(@"服务开启失败 %@",error);
    }

    self.serverSocket = serverSocket;
}

#pragma mark 有客户端的socket连接到服务器
-(void)socket:(GCDAsyncSocket *)serverSocket didAcceptNewSocket:(GCDAsyncSocket *)clientSocket{
    NSLog(@"serverSocket %@ ",serverSocket);
    NSLog(@"clientSocket %@ host:%@ port:%d",clientSocket,clientSocket.connectedHost,clientSocket.connectedPort);
    //1.保存客户端的socket
    [self.clientSockets addObject:clientSocket];

    // 2.监听客户端有没有数据上传
    //timeout -1 代表不超时
    //tag 标识作用,现在不用,就写0
    [clientSocket readDataWithTimeout:-1 tag:0];

    NSLog(@"当前有%ld 客户已经连接到服务器",self.clientSockets.count);

}

#pragma mark 读取客户端请求的数据
-(void)socket:(GCDAsyncSocket *)clientSocket didReadData:(NSData *)data withTag:(long)tag{

    // 1.把NSData转NSString
    NSString *str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];

    // 2.把当前客户端的数据 转发给 其它的客户端
    NSLog(@"接收到客户端上传的数据:%@",str);
    for (GCDAsyncSocket *socket in self.clientSockets) {
        if (socket != clientSocket) { // 不发送给发消息的客户端
            [socket writeData:data withTimeout:-1 tag:0]; 
    }
#warning 每次读完数据后,都要调用一次监听数据的方法
    [clientSocket readDataWithTimeout:-1 tag:0];
}

@end

// 客户端代码

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    // 实现聊天室
    // 1.连接到群聊服务器
    // 1.1.创建一个客户端的socket对象
    GCDAsyncSocket *clientSocket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_global_queue(0, 0)];
    self.clientSocket = clientSocket;

    // 1.2 发送连接请求
    NSError *error = nil;
    [clientSocket connectToHost:@"192.168.0.108" onPort:5288 error:&error];
    if (!error) {
        NSLog(@"%@",error);
    }

    // 2.发送聊天消息和接收聊天消息

}

-(void)socket:(GCDAsyncSocket *)clientSocket didConnectToHost:(NSString *)host port:(uint16_t)port{
    NSLog(@"与服务器连接成功");
    // 监听读取数据
    [clientSocket readDataWithTimeout:-1 tag:0];

}

// Disconnect 断开连接
-(void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err{
    NSLog(@"与服务器断开连接 %@",err);
}

#pragma mark 读取消息
-(void)socket:(GCDAsyncSocket *)clientSocket didReadData:(NSData *)data withTag:(long)tag{

    NSString *str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    NSLog(@"%@",str);
    NSLog(@"%@",[NSThread currentThread]);
    // 把消息添加到数据源
    if (str) {
        [self.dataSources addObject:str];

        // 刷新表格
#warning 要在主线程

        [[NSOperationQueue mainQueue] addOperationWithBlock:^{
            [self.tableView reloadData];
        }];
    }
    // 监听读取数据
    [clientSocket readDataWithTimeout:-1 tag:0];

}

- (IBAction)sendAction:(id)sender {
    // 发数据
    [self.clientSocket writeData:[@"hello world" dataUsingEncoding:NSUTF8StringEncoding] withTimeout:-1 tag:0];
}

上面的聊天室是基于TCP的长链接,将客户端socket从数组中移除就可以退出
XMPPFramework框架也是一种类似GCDAsyncSocket的框架,提供了一系列的方法去实现与服务端的连接和收发

图片 2图片 3

业务网是疏通电话、电报、传真、数据、图像等各类通信业务的网路,是指通信网的服务功能。按其业务种类,可分为电话网、电报网,数据网等。电话网是各种业务的基础,电报网是通过在电话电路加装电报复用设备而形成的,数据网可由传输数据信号的电话电路或专用电路构成。业务网具有等级结构,即在业务中设立不同层次的交换中心,并根据业务流量、流向、技术及经济分析,在交换机之间以一定的方式相互联接。

2.IP协议

网络层协议,规定了在互联网上确定与寻找计算机的规则。

import  socket
sk = socket.socket()    # 创建对象,构造函数里面的参数,一般都不需要参数
 # family:AF_INET-服务器之间的通信,AF_UNIX-Unix不同进程之间的通信 type:SOCK_STREAM-TCP连接,SOCK_Dgram-UDP连接
address = ('127.0.0.1',8888)
sk.bind(address)
sk.listen(3)                           # 让多少个通信进行等待
# print(sk.accept())        # 等待连接,收到的是一个元组,里面有个 socket对象,以及客户端的ip和端口
#  (<socket.socketfd=420,family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM,proto=0,laddr=('127.0.0.1',8888),raddr=('127.0.0.1',50510)>, ('127.0.0.1',50510))
conn,addr = sk.accept()                      # 会在这里阻塞,就是会在这里等着别人连接   ########注意这里用的socket对象
conn.send(bytes('不要幻想了','utf8'))     # 不能发送String类型,要发送byte类型

支撑管理网是为保证业务网正常运行,增强网路功能,提高全网服务质量而形成的网络。在支撑管理网中传递的是相应的控制、监测及信令等信号。按其功能不同,可分为信令网、同步网和管理网。信令网由信令点、信令转接点、信令链路等组成,旨在为公共信道信令系统的使用者传送信令。同步网为通信网内所有通信设备的时钟提供同步控制信号,使它们工作在同一速率上。管理网是为保持通信网正常运行和服务所建立的软、硬系统,通常可分为话务管理网和传输监控网两部分。

3.TCP协议

传输层的一种数据传输协议,数据传输前通过“三次握手”建立连接,然后再发送数据,适用于对数据准确性要求较高的情况,由于数据传输前需要建立连接,传输速度较慢。

server.py

4.UDP协议

传输层的一种数据传输协议,数据传输前不需要建立连接,适用于对数据准确性要求不高的情况,传输数据较快,一般聊天信息都通过该协议传输。

服务器通过conn.close()关掉通讯
client.py

5.HTTP协议

HTTP协议属于应用层协议,为操作系统或网络应用程序提供访问网络服务的接口。

图片 4图片 5

6.端口port

当数据到达计算机后,为了找到目标应用程序,为每一个应用程序分配了一个整数值,取值0-65535,这个整数值就是端口,从中可以看出,端口代表了计算机上一个应用程序,保证数据准确到达预定的程序。一个端口不能同时被多个应用程序占用,一个应用程序结束以后,端口不会立即释放,有一个内存延迟占有的时间,这个时间一般很短。端口、0-1023已经被系统应用程序及其他应用程序占用,程序设计时避免使用这个范围的端口。

1 import  socket
2 sk = socket.socket()
3 address = ('127.0.0.1',8888)
4 sk.connect(address)
5 data = sk.recv(1024)
6 print(str(data,'utf8'))

7.套接字Socket

套接字是数据发送与接收的工具。发送者通过套接字发送数据,接受者通过套接字监听指定的端口获取数据。

8.无论采用TCP协议,还是UDP协议,数据都只能以字节形式发送。

client.py

二 TCP程序设计

1.关闭通过Socket获取的输入流或者输出流将关闭Socket。

2.通过Socket获取的输出流输出完毕后必须关闭,不然另一端对应的输入流将阻塞。由于通过输出流对象关闭输出流时,同时关闭Socket对象,将导致另一端无法获取对应Socket的对象,因此只能通过Socket下的方法shutdownOutput关闭输出流。

客户端关闭自己的socket就可以关闭连接

3.客户端的一般步骤: 

Socket socket=new Socket(String host,int port);//创建客户端Socket,发送与接收数据,需要指明服务器IP与端口
OutputStream os=socket.getOutputStream();//获取输出流,向服务器发送数据
..........
os.flush();
socket.shutdownOutput();//关闭输出流,防止服务器端阻塞

InputStream is=socket.getInputStream();//获取输入流,输入流包含服务器的反馈信息
............

socket.close();//关闭socket,同时关闭输入与输出流

#######通讯改进一#######
每人发一条信息,不能够停止,停止可以加个判断
server.py

4.服务器的一般步骤:

ServerSocket server=new ServerSocket(int port);//建立服务器端套接字,指定监听端口
Socket socket=server.accept();//获取访问客户端的Socket,阻塞线程
InputStream is=socket.getInputStream();//获取输入流,其中包含客户端发送的数据
.............

OutputStream os=socket.getOutputStream();//获取输出流,向客户端反馈信息
..............
os.flush();
os.shutdownOutput();

server.close();

图片 6图片 7

5.Demo

 1 import  socket
 2 def  get_server_socket():
 3     sk = socket.socket()
 4     server_address = ('127.0.0.1',8888)
 5     sk.bind(server_address)
 6     sk.listen(5)
 7     return  sk
 8 if  __name__ == '__main__':
 9     sk = get_server_socket()
10     print('waiting...')
11     conn,addr = sk.accept()
12     while  True:
13         data = conn.recv(1024)
14         print(str(data,'utf8'))
15         inp = input('>>>')
16         conn.send(bytes(inp,'utf8'))
17         print('waiting...')
18     conn.close()

客户端

package com.javase.networkCommunication.tcp.demo02;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;

public class ImgClient {

    public static void main(String[] args) throws UnknownHostException, IOException {
        Socket socket = new Socket("192.168.146.1", 10007);
        FileInputStream is = new FileInputStream("Files/1.jpg");
        OutputStream os = socket.getOutputStream();
        byte[] buf = new byte[1024];// 先将数据读取到缓冲区,比频繁的从硬盘读取速度快
        int length = 0;
        while ((length = is.read(buf)) != -1) {
            os.write(buf, 0, length);
        }
        os.flush();
        socket.shutdownOutput();// 如果输出流不关闭,服务端对应的输入流会阻塞

        InputStream replyIs = socket.getInputStream();//不会阻塞线程
        byte[] buf01 = new byte[1024];
        int length01 = replyIs.read(buf01);
        String reply = new String(buf01, 0, length01);
        System.out.println(reply);

        is.close();
        socket.close();
    }

}

server.py

服务器

package com.javase.networkCommunication.tcp.demo02;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

import org.junit.Test;

public class ImgServer {

    @Test
    public void test01() throws IOException {
        ServerSocket serverSocket = new ServerSocket(10007);
        Socket socket = serverSocket.accept();// 线程阻塞,等待请求
        System.out.println("hostAddress="   socket.getInetAddress().getHostAddress());
        InputStream is = socket.getInputStream();
        FileOutputStream os = new FileOutputStream("Files/2.jpg");
        System.out.println(1);
        byte[] buf = new byte[1024];
        int length = 0;
        System.out.println(2);
        int count = 3;
        while ((length = is.read(buf)) != -1) {
            os.write(buf, 0, length);
            System.out.println(count  );
        }
        os.flush();
        os.close();
        System.out.println("图片上传结束");

        /*PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
        out.write("success");*/
        OutputStream out = socket.getOutputStream();
        out.write("success".getBytes());
        out.flush();
        socket.shutdownOutput();
        System.out.println("响应数据已发出");

        serverSocket.close();
    }

}

client.py

三 UDP程序设计

图片 8图片 9

1.数据处理方式

UDP协议以数据包的形式发送数据,每个包的最大值64k。

 1 import socket
 2 def  connect_server():
 3     sk = socket.socket()
 4     server_address = ('127.0.0.1',8888)
 5     sk.connect(server_address)
 6     return sk
 7 if __name__ == '__main__':
 8     sk = connect_server()
 9     while  True:
10         inp = input('>>>')
11         sk.send(bytes(inp,'utf8'))
12         print('waiting...')
13         data = sk.recv(1024)
14         print(str(data,'utf8'))
15     sk.close()

2.发送数据的一般步骤:

DatagramSocket socket=new DatagramSocket();//创建数据报套接字用于发送数据
//DUP协议采用数据包分段发送数据,因此需要建立数据包,在数据包中指明目的地IP与端口
DatagramPacket packet= DatagramPacket(byte buf[], int offset, int length,InetAddress address, int port);
socket.send(packet);

client.py

3.接收数据的一般步骤:

DatagramSocket socket=new DatagramSocket(int port);//创建监听指定端口的数据报套接字
DatagramPacket packet=new DatagramPacket(byte buf[], int length);
socket.receive(packet);

一 概述 1.网络模型 OSI(Open System Interconnection,开放式系统互联)模型,是对网络系统结构的概括,将网络分为七层...

 

##########通讯改进二################
客户端能正常退出
server.py

图片 10图片 11

 1 import  socket
 2 def  get_server_socket():
 3     sk = socket.socket()
 4     server_address = ('127.0.0.1',8888)
 5     sk.bind(server_address)
 6     sk.listen(5)
 7     return sk
 8 if__name__ == '__main__':
 9     sk = get_server_socket()
10     print('waiting...')
11     conn,addr = sk.accept()
12     while  True:
13         data = conn.recv(1024)
14         print(str(data,'utf8'))
15         if not data:
16             print('waitconnect...')
17             conn, addr = sk.accept()
18             continue
19         inp = input('>>>')
20         conn.send(bytes(inp,'utf8'))
21     print('waiting...')
22     conn.close()

server.py

client.py

图片 12图片 13

 1 import socket
 2 def  connect_server():
 3     sk = socket.socket()
 4     server_address = ('127.0.0.1',8888)
 5     sk.connect(server_address)
 6     return  sk
 7 if  __name__ == '__main__':
 8     sk = connect_server()
 9     while  True:
10         inp = input('>>>')
11         if  inp == 'exit':
12             break
13         sk.send(bytes(inp,'utf8'))
14         print('waiting...')
15         data = sk.recv(1024)
16         print(str(data,'utf8'))
17 
18 sk.close()

client

 

#############通讯改进三#############################
当一个客户端退出后,能够接受其他客户端的信息
server.py

图片 14图片 15

 1 import  socket
 2 def get_server_socket():
 3     sk = socket.socket()
 4     server_address = ('127.0.0.1',8888)
 5     sk.bind(server_address)
 6     sk.listen(5)
 7     return sk
 8 def get_conn(sk):
 9     print('waitconnect...')
10     conn, addr = sk.accept()
11     return conn
12 if __name__ == '__main__':
13     sk = get_server_socket()
14     conn = get_conn(sk)
15     while  True:
16         try:
17             data = conn.recv(1024)
18             ##Linux这里不会报错,如果强行关闭了conn,data就会变成空,也就是说Linux的直接不try就行了。
19         except Exception as e:
20             conn = get_conn(sk)
21         print(str(data,'utf8'))
22         if not data:
23             conn = get_conn(sk)
24             continue
25         inp = input('>>>')
26         conn.send(bytes(inp,'utf8'))
27         print('waiting...')
28         conn.close()

View Code

client.py

图片 16图片 17

 1 import socket
 2 def  connect_server():
 3     sk = socket.socket()
 4     server_address = ('127.0.0.1',8888)
 5     sk.connect(server_address)
 6     return sk
 7 if __name__  == '__main__':
 8     sk = connect_server()
 9     while True:
10         inp = input('>>>')
11         if inp == 'exit':
12             break
13         sk.send(bytes(inp,'utf8'))
14         print('waiting...')
15         data = sk.recv(1024)
16         print(str(data,'utf8'))
17     sk.close()

client.py

 

 

 

# 流程描述:
#
# 1 服务器根据地址类型(ipv4,ipv6)、socket类型、协议创建socket
#
# 2 服务器为socket绑定ip地址和端口号
#
# 3 服务器socket监听端口号请求,随时准备接收客户端发来的连接,这时候服务器的socket并没有被打开
#
# 4 客户端创建socket
#
# 5 客户端打开socket,根据服务器ip地址和端口号试图连接服务器socket
#
# 6 服务器socket接收到客户端socket请求,被动打开,开始接收客户端请求,直到客户端返回连接信息。这时候socket进入阻塞状态,所谓阻塞即accept()方法一直等到客户端返回连接信息后才返回,开始接收下一个客户端连接请求
#
# 7 客户端连接成功,向服务器发送连接状态信息
#
# 8 服务器accept方法返回,连接成功
#
# 9 客户端向socket写入信息(或服务端向socket写入信息)
#
# 10 服务器读取信息(客户端读取信息)
#
# 11 客户端关闭
#
# 12 服务器端关闭

sk.bind(address)
#s.bind(address) 将套接字绑定到地址。address地址的格式取决于地址族。在AF_INET下,以元组(host,port)的形式表示地址。
sk.listen(backlog)
#开始监听传入连接。backlog指定在拒绝连接之前,可以挂起的最大连接数量。
#backlog等于5,表示内核已经接到了连接请求,但服务器还没有调用accept进行处理的连接个数最大为5
      #这个值不能无限大,因为要在内核中维护连接队列
sk.setblocking(bool)
#是否阻塞(默认True),如果设置False,那么accept和recv时一旦无数据,则报错。
sk.accept()
#接受连接并返回(conn,address),其中conn是新的套接字对象,可以用来接收和发送数据。address是连接客户端的地址。
#接收TCP 客户的连接(阻塞式)等待连接的到来
sk.connect(address)
#连接到address处的套接字。一般,address的格式为元组(hostname,port),如果连接出错,返回socket.error错误。
sk.connect_ex(address)
#同上,只不过会有返回值,连接成功时返回 0 ,连接失败时候返回编码,例如:10061
sk.close()
#关闭套接字
sk.recv(bufsize[,flag])
#接受套接字的数据。数据以字符串形式返回,bufsize指定最多可以接收的数量。flag提供有关消息的其他信息,通常可以忽略。
sk.recvfrom(bufsize[.flag])
#与recv()类似,但返回值是(data,address)。其中data是包含接收数据的字符串,address是发送数据的套接字地址。
sk.send(string[,flag])
#将string中的数据发送到连接的套接字。返回值是要发送的字节数量,该数量可能小于string的字节大小。即:可能未将指定内容全部发送。
sk.sendall(string[,flag])
#将string中的数据发送到连接的套接字,但在返回之前会尝试发送所有数据。成功返回None,失败则抛出异常。
#内部通过递归调用send,将所有内容发送出去。
sk.sendto(string[,flag],address)
#将数据发送到套接字,address是形式为(ipaddr,port)的元组,指定远程地址。返回值是发送的字节数。该函数主要用于UDP协议。
sk.settimeout(timeout)
#设置套接字操作的超时期,timeout是一个浮点数,单位是秒。值为None表示没有超时期。一般,超时期应该在刚创建套接字时设置,因为它们可能用于连接的操作(如 client 连接最多等待5s )
sk.getpeername()
#返回连接套接字的远程地址。返回值通常是元组(ipaddr,port)。
sk.getsockname()
#返回套接字自己的地址。通常是一个元组(ipaddr,port)
sk.fileno()
#套接字的文件描述符

来自 <;

 

本文由必赢棋牌官网发布于科技动态,转载请注明出处:互连网通讯技巧

上一篇:科学家首次远程传递“心灵感应”信息 下一篇:没有了
猜你喜欢
热门排行
精彩图文
  • 光纤通信有哪些特点详解
    光纤通信有哪些特点详解
    光纤即为光导纤维的简称。光纤通信是以光波作为信息载体,以光纤作为传输媒介的一种通信方式。从原理上看,构成光纤通信的基本物质要素是光纤、光
  • 煤渣 英文版
    煤渣 英文版
    往路面上撒煤渣是为了增加磨擦力。煤渣撒在路面上,磨擦力增大了,汽车和人在路面上走就不那么滑了。另外,煤渣容易吸热,往雪上撒煤渣,雪就化得
  • 醋有效期是多长期 醋能放多长时间
    醋有效期是多长期 醋能放多长时间
    豆芽含水量高,在烹调时易出汤,经不起长时间的加热。放点醋可以使豆芽既断生,又不出水软化,因为醋酸对蔬菜中的蛋白质有显著的凝固的作用,可使
  • 冻肉速速变回“小鲜肉”,这方式忒方便了!
    冻肉速速变回“小鲜肉”,这方式忒方便了!
    鲜、冻肉是家园烹调理外出吃饭至关重要的优质动物蛋白来源。在食用肉类的同期,要注意安全和正规,国家市镇监督管理总部特地提示如下: 大繁多人因
  • 中性(neutrality)体质是百病之源!那9条中性(
    中性(neutrality)体质是百病之源!那9条中性(
    过去的2018年,你可能因为看到“酸性体质是百病之源?”的新闻而努力让自己变成碱性体质;也可能因问题疫苗事件的爆发而对疫苗失去信任……事实是这样