网络层代码设计

主要从 2 个方面,一部分从 unix 编程到 linux,一部分从 Vc 的 winsock 编程设计,不过 winsock 早期网上资料是不考虑粘包的问题,所以用起来会有问题。
目前常规网上例子的代码和之前一样,对比实际工作代码差异是很大,这个也不完全是错误,只是过旧了。网上例子是 Tcp,Udp 传输最普通的字符串流和二进制流。字符串都可以发送的,原因是载入缓存区或者本地内存里最终都是会变成 2 进制。另外有些例子和现实中会要求转换 str 和"hex"16 进制只是为了帮助调式。

echo 服务

网上的例子等于是 echo(回显或者回声)服务。
这个很有用的,比如在设计服务器框架里会预留一个空接口或者客户端发什么,服务器回什么来测试网络层以及验证服务器状态。‘
(根据实际情况来,有可能是带包头 + 包体的)因为 echo 服务本身结构接收是以客户端为主,允许没有结构体概念,客户端发什么消息投递的 IP 和端口正确,只要服务器开启中,服务器就照样子返回一份。
不过会有以下的问题,如果是 TCP 允许客户端不停发,服务器不停回,但不是发一条客户端信息就被转换二进制压包到 Tcp 层然后指向 IP 层。那么常规的字符串会出现这个问题,客户端连续发送 5 个 10 个字节的,服务器那边有可能只会拿到 3 个包 15,15,20 字节,但总量是 50 个字节。

关注字符串类型

字符串因为每次发送数据不是一次并且不是固定的,所以是一个动态的。如果是 C++ 和 C# 等语言需要考虑用 vector,另外我们先看看要用到那些

#include <string.h>
#include <vector>
#include <sstream>
#include <string>
#include <time.h>
#include <sstream>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <iostream>
#ifndef _WIN32
#include <sys/socket.h>
#include <ifaddrs.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
  1. 需要添加函数处理逻辑 static 切割字符串进入容器 方法 static 处理传入任意参数 static 不同格式的互转 static 获取网络 IP 定义 char n_Ip static 字符串替换部分/全部 static 字符串拷贝。 拿一段字符串库处理 IP 的作为例子
static string getAddress(const char* p_Interface)
    {
        char   szHostIp[32];;
        memset(szHostIp,0,sizeof(szHostIp)); #初始化内存填充
        struct ifaddrs * pAddr0, *pAddr1;
        char* pChar = NULL ;
        memset(szHostIp,0,sizeof(szHostIp));

                if (getifaddrs(&ifaddr) == -1) {
                      return -1;
                }
                pAddr1 = pAddr0
        for(; NULL != pAddr1 ; pAddr1 = (*pAddr1 ).ifa_next){ #中段条件一直判断布尔
        {
            if(0 == strcmp(pInterface,pAddr1->ifa_name)) #比较变量
            {
                if(pAddr1->ifa_addr == NULL)
                {
                    continue;
                }
                if(AF_INET == pAddr1->ifa_addr->sa_family)
                {
                    struct sockaddr_in * addr4 = (struct sockaddr_in *)pAddr1->ifa_addr;  # #include <netinet/in.h>有关,在sockaddr_in 前面需要加struct
                    pChar = inet_ntoa(addr4->sin_addr);
                    if(NULL != pChar)
                    {
                        if(strncpy(szHostIp,pChar,sizeof(szHostIp)-1))
                        {
                            break ;
                        }
                    }
                }
            }
            else
            {
                continue;
            }
        }
        string tempStr = "";
        if(szHostIp[0] != '\0')
        {
            tempStr = StringUtils::chars2string(szHostIp,strlen(szHostIp)); #charstring      
        }

        freeifaddrs(pAddr0);

        return tempStr;
    }


↙↙↙阅读原文可查看相关链接,并与作者交流