不同语言不同平台可以通信吗?JSON做序列化会粘包吗?附粘包处理

Posted 看,未来

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了不同语言不同平台可以通信吗?JSON做序列化会粘包吗?附粘包处理相关的知识,希望对你有一定的参考价值。

我在做的事,不要问。猜到了,不要说。等我做完,自会成一个系列。

Windows 和 Linux可以通信吗?

emmm,emmm,我说不能你信吗?

难道Windows上应用背后的服务器都是部署在Windows上吗?

那怎么通信,通信的时候需要注意什么呢?这第一步,也是磕磕碰碰,毕竟从一年半前写那个分布式管理系统之后就没再这样分两个平台通信了。

如果一开始通信的时候就报错:由于连接方在一段时间后没有正确应答或连接的主机没有反应。有这么几个情况,绕到最后就是一个情况,ping不通。
所以ping一下试试看。

不通怎么办?我早上发了一篇关闭防火墙的博客。嗯。


我是C++的服务器,Python的客户端呢?

为什么要用不同的语言呢?因为相同语言已经玩过好多次了,直接用结构体极快,都不用中间人了。但是,我要走出舒适区。

为什么选Python呢?因为除了C++,我就只会Python这个稍微大点的语言了。我总不能拿 R 语言,SQL语言,Shell语言去写个客户端吧。

通信的时候需要注意什么呢?不同语言的数据类型的大小不一定是一样的,这个要小心。


JSON、PB等序列化方式也会粘包吗?

PB我还没去用过,JSON亲测会粘包。
其实我觉得,粘不粘包不是我用什么方式来序列化说了算的吧。我觉得这应该是TCP说了算哈。
只要TCP它一天要粘包,不管我用什么序列化方式它就是要粘包吧。


粘包处理

好了不废话了,直接放码过去吧。

Server端

这里我比较关心一点哈:我用来构造发送字符串的那个字符串要怎么复用啊???
明白了,自己写个缓冲区。
这里毕竟是个demo哈,所以缓冲区我就不附带了,可以去我主页置顶的那篇里面有缓冲区设计的链接。

#include <iostream>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>

#include <string>
#include <map>

#include"json.hpp"
using json = nlohmann::json; 
using namespace std;

int main()
{
    json js;

    map<string,string> mss;
    mss.insert({"name","wlf"});  
    mss.insert({"age","21"});   

    vector<int> vc = {1,2,3,4,5,6,7,8,9};

    js["name"] = "wlf";
    js["age"] = "21";
    js["path"] = mss;
    js["vc"] = vc;

    string s = js.dump();   //和Python里面的一样
    s = to_string(s.length()) + s;
    cout<<s<<endl;
    const char* str_body = s.c_str();


    //创建套接字
    int serv_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    //将套接字和IP、端口绑定
    struct sockaddr_in serv_addr;
    bzero(&serv_addr,sizeof(serv_addr));                      //每个字节都用0填充
    serv_addr.sin_family = AF_INET;                           //使用IPv4地址
    serv_addr.sin_addr.s_addr = inet_addr(""); //具体的IP地址
    serv_addr.sin_port = htons(8889);                         //端口
    bind(serv_sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr));
    //进入监听状态,等待用户发起请求
    listen(serv_sock, 20);
    //接收客户端请求
    struct sockaddr_in clnt_addr;
    socklen_t clnt_addr_size = sizeof(clnt_addr);

    cout<<"Acceptting···"<<endl;

    int clnt_sock = accept(serv_sock, (struct sockaddr *)&clnt_addr, &clnt_addr_size);

    while (1)
    {
        //向客户端发送数据
        write(clnt_sock, str_body, strlen(str_body)); //这里不能用sizeof
    }

    return 0;
}

Client 端

from socket import *
import json
HOST = ''  # or 'localhost'
PORT = 8889
# BUFSIZ = 1024
ADDR = (HOST, PORT)

tcpCliSock = socket(AF_INET, SOCK_STREAM)
tcpCliSock.connect(ADDR)
while True:

    # data = tcpCliSock.recv(BUFSIZ)
    # print(data.decode('utf-8'))
    data1 = tcpCliSock.recv(2)
    if not data1:
        break
    lenth = int(data1.decode('utf-8'))
    data2 = tcpCliSock.recv(lenth)

    print(data2.decode('utf-8'))
    # js_data = json.loads(data1)
    # print(js_data['name'])
tcpCliSock.close()

最后啊,我还发现这个测试,不用联网,上次在知乎看到有人问这个,我去耍会儿,再回来把这个问题给做一下,看看本机通信是怎么个流程,会不会比pipe要快,毕竟nginx用sockpair而不用pipe到底是为什么我还是没明白。

以上是关于不同语言不同平台可以通信吗?JSON做序列化会粘包吗?附粘包处理的主要内容,如果未能解决你的问题,请参考以下文章

多平台下的数据存储新秀-PROTOBUF

python 不同数据类型的序列化

常用模块2

不同编程语言访问的套接字可以通信吗?

Google 协议缓冲区可以在不同语言之间进行序列化/解析吗?

Google 协议缓冲区可以在不同语言之间进行序列化/解析吗?