linux 网络编程基础---1

2019-07-12 18:28发布

data/attach/1907/r4h8mbdkhrjr602at8st78hk2tjw3kob.jpgdata/attach/1907/gzrx243jdqea6iy3mldq3xvgp96n372n.jpg 嵌入式Linux网络编程      1、掌握TCP/IP协议的基础知识       2、掌握嵌入式Linux基础网络编程       3、掌握嵌入式Linux高级网络编程       4、能够独立编写客户端、服务器端的通信程序  
 一、TCP/IP协议的基础知识       1、TCP协议分成了两个不同的协议:     (1)用来检测网络传输中差错的传输控制协议TCP    (2)专门负责对不同网络进行互联的互联网协议IP
    2、网络的体系结构     概念网络采用分而治之的方法设计,将网络的功能划分为不同的模块,以分层的形式有机组合在一起。     每层实现不同的功能,其内部实现方法对外部其他层次来说是透明的。每层向上层提供服务,同时使用下层提供的服务     网络体系结构即指网络的层次结构和每层所使用协议的集合。     常用体系结构有:     (1)OSI     (2)TCP/IP
    OSI参考模型及TCP/IP参考模型 
    
    3、TCP/IP协议族     常用协议
    TCP(Transport Control Protocol)传输控制协议     IP(Internetworking Protocol)网间协议     UDP(User Datagram Protocol)用户数据报协议     ICMP(Internet Control Message Protocol)互联网控制信息协议     SMTP(Simple Mail Transfer Protocol)简单邮件传输协议     SNMP(Simple Network manage Protocol)简单网络管理协议     HTTP(Hypertext Transfer Protocol) 超文本传输协议     FTP(File Transfer Protocol)文件传输协议     ARP(Address Resolution Protocol)地址解析协议
    4、TCP和UDP协议     TCP:是一种面向连接的传输层协议,它能提供高可靠性通信(即数据无误、数据无丢失、数据无失序、数据无重复到达的通信。     
    适用情况:     (1)适合于对传输质量要求较高,以及传输大量数据的通信。     (2)在需要可靠数据传输的场合,通常使用TCP协议     (3)MSN/QQ等即时通讯软件的用户登录账户管理相关的功能通常采用TCP协议
    UDP(User Datagram Protocol)用户数据报协议,是不可靠的无连接的协议。在数据发送前,因为不需要进行连接,所以可以进行高效率的数据传输。     适用情况:     (1)在接收到数据,给出应答较困难的网络中使用UDP。(如:无线网络)     (2)适合于广播/组播式通信中。     (3)MSN/QQ/Skype等即时通讯软件的点对点文本通讯以及音视频通讯通常采用UDP协议     (4)流媒体、VOD、VoIP、IPTV等网络多媒体服务中通常采用UDP方式进行实时数据传输
    同时,一个UDP应用可同时作为应用的客户或服务器方。由于UDP协议并不需要建立一个明确的连接,因此建立UDP应用要比建立TCP应用简单得多。



二、网络基础编程
    1、网络编程常用函数关API         socket() 创建套接字     bind() 绑定本机地址和端口     connect() 建立连接     listen() 设置监听端口     accept() 接受TCP连接     recv(), read(), recvfrom() 数据接收     send(), write(), sendto() 数据发送     close(), 关闭套接字



    1、创建socket          #include <sys/types.h>          /* See NOTES */        #include <sys/socket.h>
       int socket(int domain, int type, int protocol);
         该函数用于建立一个socket连接,可指定socket类型等信息。在建立了socket连接之后,可对sockaddr或sockaddr_in结构进行初始化,以保存所建立的socket地址信息。
    2、绑定端口/IP        #include <sys/types.h>          /* See NOTES */
       #include <sys/socket.h>
       int bind(int sockfd, const struct sockaddr *addr,
                socklen_t addrlen);

            bind():该函数是用于将本地IP地址绑定到端口号,若绑定其他IP地址则不能成功。另外,它主要用于TCP的连接,而在UDP的连接中则无必要。
    3、监听连接请求(非阻塞)        #include <sys/types.h>          /* See NOTES */
       #include <sys/socket.h>
       int listen(int sockfd, int backlog);
       listen():在服务端程序成功建立套接字和与地址进行绑定之后,还需要准备在该套接字上接收新的连接请求。此时调用listen()函数来创建一个等待队列,在其中存放未处理的客户端连接请求。
    4、连接请求(阻塞)        #include <sys/types.h>          /* See NOTES */
       #include <sys/socket.h>
       int connect(int sockfd, const struct sockaddr *addr,
                   socklen_t addrlen);       connect():该函数在TCP中是用于bind()的之后的client端,用于与服务器端建立连接,如果服务端一直没有处理连接请求,那么函数将会阻塞,一直等待连接成功。。而在UDP中由于没有了bind()函数。         connect()有点类似bind()函数的作用。
    5、接收连接请求(阻塞)        #include <sys/types.h>          /* See NOTES */
       #include <sys/socket.h>
       int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
       #define _GNU_SOURCE             /* See feature_test_macros(7) */
       #include <sys/socket.h>
       int accept4(int sockfd, struct sockaddr *addr,
                   socklen_t *addrlen, int flags);          accept():服务端程序调用listen()函数创建等待队列之后,调用accept()函数等待并接收客户端的连接请求。     它通常从由bind()所创建的等待队列中取出第一个未处理的连接请求。          6、发送与接收数据(阻塞)       #include <sys/types.h>
       #include <sys/socket.h>
       ssize_t send(int sockfd, const void *buf, size_t len, int flags);
       ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
                      const struct sockaddr *dest_addr, socklen_t addrlen);
       ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags);
         send()和recv():这两个函数分别用于发送和接收数据,可以用在TCP中,也可以用在UDP中。当用在UDP时,可以在connect()函数建立连接之后再用。
       #include <sys/types.h>
       #include <sys/socket.h>

       ssize_t recv(int sockfd, void *buf, size_t len, int flags);

       ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
                        struct sockaddr *src_addr, socklen_t *addrlen);

       ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags);


  sendto()和recvfrom():这两个函数的作用与send()和recv()函数类似,也可以用在TCP和UDP中。当用在TCP时,后面的几个与地址有关参数不起作用,函数作用等同于send()和recv();当用在UDP时,可以用在之前没有使用connect()的情况下,这两个函数可以自动寻找指定地址并进行连接。



/* function name : server.c */

#include<sys/types.h>
#include<sys/socket.h>
#include<stdio.h>
#include<stdlib.h>
#include<errno.h>
#include<string.h>
#include<netinet/in.h>

/* Macro Definition */
#define NET_PORT 7777
#define IP_ADDRESS "192.168.1.109"

/* Gobal Varialb */
pthread_t Pth_rd,Pth_wr;//定义读写线程id
int socket_fd,new_sockfd;//定义socket文件描述符

/*
 *    函数描述:接收数据线程
 */

void* pthrecv(void *arg)
{
    char buffer[100];
    while(1)    
    {
        bzero(buffer,sizeof(buffer));//清空缓冲区

        // 从new_socket读取信息,并存放在buffer中
        //若无数据发送,则此函数将会阻塞
        int num = recv(new_sockfd,buffer,sizeof(buffer), 0);
        buffer[num] = '