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