对于socket网络编程,捣鼓了一周多,终于实现了电脑为服务端,学习板为客户端之间的通信

最开始是网上找到相关的客户端,和服务端 的程序,然后试着去理解,但是这个过程很难过,因为从来没有接触过的,但是没办法,只能硬着头皮啃,问老师,问学长,网上看视频。终于是吧他啃下来了。

服务端的代码:

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define BACKLOG 100  
 
int main()  
{
    int iListenSock = socket(AF_INET, SOCK_STREAM, 0);
//int socket(int domain, int type, int protocol);socket函数对应于普通文件的打开操作。普通文件的打开操作返回一个文件描述字,而socket()用于创建一个socket描述符(socket descriptor),它唯一标识一个socket。这个socket描述字跟文件描述字一样,后续的操作都有用到它,把它作为参数,通过它来进行一些读写操作。
//1.协议族决定了socket的地址类型,在通信中必须采用对应的地址,如AF_INET决定了要用ipv4地址(32位的)与端口号(16位的)的组合、AF_UNIX决定了要用一个绝对路径名作为地址。
//2.type:指定socket类型。常用的socket类型有,SOCK_STREAM、SOCK_DGRAM、SOCK_RAW、SOCK_PACKET、SOCK_SEQPACKET等等
//3.protocol故名思意,就是指定协议。常用的协议有,IPPROTO_TCP、IPPTOTO_UDP、IPPROTO_SCTP、IPPROTO_TIPC等,它们分别对应TCP传输协议、UDP传输协议、STCP传输协议、TIPC传输协议
    sockaddr_in addr;//
    memset(&addr, 0, sizeof(addr));
    inet_aton("192.168.1.66", &addr.sin_addr);
//是一个改进的方法来将一个字符串IP地址转换为一个32位的网络序列IP地址。
/*     struct sockaddr_in     
          {  unsigned short int sin_family;//协议族(family)连接方式        
              uint16_t sin_port;//定义端口号,可以直接指定,也可由系统指定,也是网络字节序,
                                 一般用htons()函数转换。        
              struct in_addr sin_addr;//为ip地址,是二进制的网络字节序,
                                           一般用inet_addr()函数完成转换        
              unsigned char sin_zero[8];//一般不使用    
 }
    */
    addr.sin_family = AF_INET;//协议族(family)采用IPv4网络协议
    addr.sin_port = htons(8888);//服务器监听端口号 8888 
 
    int iOpt = 1;
    setsockopt(iListenSock, SOL_SOCKET, SO_REUSEADDR, &iOpt, sizeof(iOpt)); // 标配
    bind(iListenSock, (sockaddr*)&addr, sizeof(addr));//bind()函数把一个地址族中的特定地址赋给socket。例如对应AF_INET、AF_INET6就是把一个ipv4或ipv6地址和端口号组合赋给socket。
    listen(iListenSock, BACKLOG);//BACKLOG 100指定同时能够处理的最大连接要求 
    epoll_event ev;
    ev.data.fd = iListenSock;
    ev.events = EPOLLIN;
    
    epoll_event events[BACKLOG + 1];
 
    int epollFD = epoll_create(BACKLOG + 1);   // 告诉内核监测的数目, 返回的epollFD为epoll管理句柄
    epoll_ctl(epollFD, EPOLL_CTL_ADD, iListenSock, &ev);  // 将ev和对应的iListenSock添加到epoll句柄,用于被epollFD管理
    while(1) 
    {
        int timeoutMS = -1; // 永不超时
        int nfds = epoll_wait(epollFD, events, BACKLOG + 1, timeoutMS);   // events和nfds是一对输出值
        printf("nfds is %d\n", nfds);
        
        for(int i = 0; i < nfds; i++) 
        {  
            if(events[i].data.fd == iListenSock)         // 用于监听客户端连接的socket
            {  
                int iConnSock = accept(iListenSock, NULL, NULL);
                if (iConnSock < 0)
 
                {
                    continue;
                }
 
                ev.data.fd = iConnSock;
                ev.events = EPOLLIN;
                epoll_ctl(epollFD, EPOLL_CTL_ADD, iConnSock, &ev);  // 将ev和对应的iConnSock添加到epoll句柄,用于被epollFD管理
 
                printf("new sock came, fd is %d\n", iConnSock);
            } 
            else 
            {
                int iConnSock = events[i].data.fd;      // 用于通信的socket
                char szBuf[1024] = {0};
                int recvLen = recv(iConnSock, szBuf, sizeof(szBuf) - 1, 0);
                if (recvLen > 0) 
                {  
                    printf("recv data [%s] from fd [%d]\n", szBuf, iConnSock);
                }
                else if(0 == recvLen)
                {  
                    ev.data.fd = iConnSock;
                    epoll_ctl(epollFD, EPOLL_CTL_DEL, iConnSock, &ev);
                    close(iConnSock);
                    printf("connection closed, local fd is [%d]\n", iConnSock);
                }
                else
                {
                    ev.data.fd = iConnSock;
                    epoll_ctl(epollFD, EPOLL_CTL_DEL, iConnSock, &ev);
                    close(iConnSock);
                    printf("recv error, local fd is [%d]\n", iConnSock);
                }
            }  
        }  
    }  
    
    close(epollFD);
    close(iListenSock);
    return 0;
}  

虽然程序搞懂了,但是对于网络配置的,还是不懂,在其中遇到,PC,虚拟机,板子的网络Ping通

主要问题如下

对于socket网络编程,捣鼓了一周多,终于实现了电脑为服务端,学习板为客户端之间的通信_第1张图片

这个是因为程序里面的IP地址不是你服务器的地址,导致虽然在虚拟机和板子网络可以ping得通,但是运行客户端的程序没有反应。解决方法,通过在虚拟机输入ifconfig 查看IP地址。

接下来可能会出现接来的问题;

对于socket网络编程,捣鼓了一周多,终于实现了电脑为服务端,学习板为客户端之间的通信_第2张图片

你发现你的Ip地址好像没有,

这可能是你要去开启你的网卡设置。

对于socket网络编程,捣鼓了一周多,终于实现了电脑为服务端,学习板为客户端之间的通信_第3张图片

对于socket网络编程,捣鼓了一周多,终于实现了电脑为服务端,学习板为客户端之间的通信_第4张图片

 

 

按照步骤走,IP可以自己选择,也可以选择自动,但是还是自己输入比较好,因为要选择跟板子上通一个网段。

我通过交叉编译得到了板子上linux可执行程序,许多方便改变,这个也是一个大问题,我尝试了很久通过NFS但是就是设置不好服务端的文件。最后还是选择了用u盘挂载,

 

对于socket网络编程,捣鼓了一周多,终于实现了电脑为服务端,学习板为客户端之间的通信_第5张图片

 

你可能感兴趣的:(对于socket网络编程,捣鼓了一周多,终于实现了电脑为服务端,学习板为客户端之间的通信)