本文介绍了TCP链接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要向服务器发送事件...
我要发送的事件是...
d-> asyncEvent.printOn(std :: cout);
下面给出的编的..

#include"Mouse3D.h"
#include"DevicesManager.h"
#include"Event.h"
#include< iostream>
使用名称空间hid;

命名空间connexion_3d
{
const UInt32用法:: MULTIAXIS_CONTROLLER_USAGE = 0x08;
const UInt32用法:: PRIMARY_USAGE_PAGE = 0x01;
const UInt32用法:: USAGE_PAGE_BUTTON = 0x09;
const UInt32用法:: USAGE_X = 0x30;
const UInt32用法:: USAGE_Y = 0x31;
const UInt32用法:: USAGE_Z = 0x32;
const UInt32用法:: USAGE_RX = 0x33;
const UInt32用法:: USAGE_RY = 0x34;
const UInt32用法:: USAGE_RZ = 0x35;
const UInt32用法:: USAGE_PAGE_LED = 0x08;
const UInt32用法:: USAGE_GENERIC_INDICATOR = 0x4B;

用法::用法():
txMin(0),txMax(0),rxMin(0),rxMax(0),
tyMin(0),tyMax(0),ryMin(0),ryMax(0),
tzMin(0),tzMax(0),rzMin(0),rzMax(0),
ButtonsNumber(0)
{}




const unsigned int Mouse3D :: QUEUE_SZ = 256;
const unsigned char Mouse3D :: LED_ON = 0x01;
const unsigned char Mouse3D :: LED_OFF = 0x00;
Mouse3D :: Mouse3D(const IOHIDDeviceRef& _device):device(_device),usages(),queue(HIDDevice :: makeQueue(_device,QUEUE_SZ)),valid(false),ledElement(NULL),isOpen(false),asyncEvent( )
{
setup();
}

Mouse3D :: ~~ Mouse3D()
{
releaseQueue();
}

void Mouse3D :: releaseQueue()
{
如果(队列)
{
IOHIDQueueStop(queue);
CFRelease(队列);
队列= NULL;
}
}

void Mouse3D :: setup()
{
如果(设备&&队列)
{
如果(setupElements())
{
asyncEvent.buttons.resize(usages.buttonsNumber);
IOHIDQueueStart(queue);
有效= true;
}
}
}

void Mouse3D :: open()
{
isOpen = true;
ledOn();
}

void Mouse3D :: close()
{
isOpen = false;
ledOff();
}

无符号的简短Mouse3D :: buttonsNumber()const
{
返回usages.buttonsNumber;
}

常量用法Mouse3D :: usage()const
{
返回用法;
}

bool Mouse3D :: ledOn()const
{
返回writeOnLed(LED_ON);
}

bool Mouse3D :: ledOff()const
{
返回writeOnLed(LED_OFF);
}

bool Mouse3D :: writeOnLed(unsigned char v)const
{
如果(ledElement)
{
IOHIDValueRef vref = IOHIDValueCreateWithIntegerValue(kCFAllocatorDefault,ledElement,0,v);
如果(vref)
{
IOReturn tIOReturn = IOHIDDeviceSetValue(设备,ledElement,vref);
CFRelease(vref);
return kIOReturnSuccess == tIOReturn;
}
}
返回false;
}

bool Mouse3D :: setupElements()
{
CFArrayRef元素= IOHIDDeviceCopyMatchingElements(device,NULL,0);
如果(元素)
{
usages.buttonsNumber = 0;
CFIndex idx,cnt = CFArrayGetCount(elements);
for(idx = 0; idx< cnt; idx ++)
{
IOHIDElementRef eref =(IOHIDElementRef)CFArrayGetValueAtIndex(elements,idx);
如果(eref)
{
如果(!HIDIsValidElement(eref))继续;

uint32_t usagePage = IOHIDElementGetUsagePage(eref);
uint32_t用法= IOHIDElementGetUsage(eref);

IOHIDElementType eleType = IOHIDElementGetType(eref);
if(eleType == kIOHIDElementTypeOutput)
{
if(usagePage ==用法:: USAGE_PAGE_LED&&用法==用法:: USAGE_GENERIC_INDICATOR)
ledElement = eref;
}

如果(eleType> kIOHIDElementTypeInput_ScanCodes)继续; //跳过非输入元素类型


如果(!usagePage ||!usage)继续;
如果(-1 ==用法)继续;

//HIDDumpElementInfo(eref);
开关(usagePage)
{
案例用法:: PRIMARY_USAGE_PAGE:
开关(用途)
{
案例用法:: USAGE_X:
IOHIDQueueAddElement(queue,eref);
usages.txMin = IOHIDElementGetLogicalMin(eref);
usages.txMax = IOHIDElementGetLogicalMax(eref);
休息;

大小写用法:: USAGE_Y:
IOHIDQueueAddElement(queue,eref);
usages.tyMin = IOHIDElementGetLogicalMin(eref);
usages.tyMax = IOHIDElementGetLogicalMax(eref);
休息;

案例用法:: USAGE_Z:
IOHIDQueueAddElement(queue,eref);
usages.tzMin = IOHIDElementGetLogicalMin(eref);
usages.tzMax = IOHIDElementGetLogicalMax(eref);
休息;

案例用法:: USAGE_RX:
IOHIDQueueAddElement(queue,eref);
usages.rxMin = IOHIDElementGetLogicalMin(eref);
usages.rxMax = IOHIDElementGetLogicalMax(eref);
休息;

案例用法:: USAGE_RY:
IOHIDQueueAddElement(queue,eref);
usages.ryMin = IOHIDElementGetLogicalMin(eref);
usages.ryMax = IOHIDElementGetLogicalMax(eref);
休息;

案例用法:: USAGE_RZ:
IOHIDQueueAddElement(queue,eref);
usages.rzMin = IOHIDElementGetLogicalMin(eref);
usages.rzMax = IOHIDElementGetLogicalMax(eref);
休息;
}
休息;

案例用法:: USAGE_PAGE_BUTTON:
IOHIDQueueAddElement(queue,eref);
usages.buttonsNumber ++;
休息;
}
}
}
CFRelease(elements);
返回true;
}
返回false;
}


bool Mouse3D :: read(Event3D& event)const
{
如果(!(queue&& device))返回false;

IOHIDValueRef vref = IOHIDQueueCopyNextValue(queue);
如果(!vref)返回false;
CFRelease(vref);

CFIndex值= IOHIDValueGetIntegerValue(vref);

IOHIDElementRef eref = IOHIDValueGetElement(vref);
如果(!eref)返回false;

uint32_t usagePage = IOHIDElementGetUsagePage(eref);
uint32_t用法= IOHIDElementGetUsage(eref);

如果(!usagePage ||!usage)返回false;
如果(-1 ==用法)返回false;

开关(usagePage)
{
案例用法:: PRIMARY_USAGE_PAGE:
开关(用途)
{
case用法:: USAGE_X:event.tx = value;休息;
用法:: USAGE_Y:event.ty =值;休息;
case用法:: USAGE_Z:event.tz = value;休息;
case用法:: USAGE_RX:event.rx = value;休息;
用法:: USAGE_RY:event.ry =值;休息;
case用法:: USAGE_RZ:event.rz = value;休息;
}
休息;

案例用法:: USAGE_PAGE_BUTTON:
event.buttons [用法-1] =(值== 1);休息;
休息;
}
返回true;
}

std :: string Mouse3D :: manufacturerString()
{
返回HIDDevice :: toStdString(IOHIDDevice_GetManufacturer(device));
}

std :: string Mouse3D :: productString()
{
返回HIDDevice :: toStdString(IOHIDDevice_GetProduct(device));
}

IOHIDDeviceRef Mouse3D :: hidDevice()
{
返回设备;
}

void Mouse3D :: hidDevice(IOHIDDeviceRef _device)
{
releaseQueue();

设备= _设备;
队列= HIDDevice :: makeQueue(_device,QUEUE_SZ);
有效=假;
ledElement = NULL;

setup();
如果(isOpen)open();
}

bool Mouse3D :: isValid()const
{
返回有效;
}

void Mouse3D :: invalid()
{
有效=假;
}



void Mouse3D :: deviceValueCallback(void * inContext,IOReturn inResult,void * inSender,IOHIDValueRef inIOHIDValueRef)
{
//#pragma未使用(inSender)
IOHIDElementRef eref = IOHIDValueGetElement(inIOHIDValueRef);
如果(!eref)返回;



IOHIDDeviceRef tIOHIDDeviceRef = IOHIDElementGetDevice(eref);
如果(!tIOHIDDeviceRef)返回;

Mouse3D * d =(Mouse3D *)inContext;
如果(!d)返回;

std :: cout<< std :: endl;

UInt32 usagePage = IOHIDElementGetUsagePage(eref);
UInt32的用法= IOHIDElementGetUsage(eref);

如果(!usagePage ||!usage)返回;
如果(-1 ==用法)返回;

//HIDDumpElementInfo(eref);
CFIndex值= IOHIDValueGetIntegerValue(inIOHIDValueRef);

开关(usagePage)
{
案例用法:: PRIMARY_USAGE_PAGE:
开关(用途)
{
案例用法:: USAGE_X:d-> asyncEvent.tx =值;休息;
案例用法:: USAGE_Y:d-> asyncEvent.ty =值;休息;
情况用法:: USAGE_Z:d-> asyncEvent.tz =值;休息;
情况用法:: USAGE_RX:d-> asyncEvent.rx =值;休息;
情况用法:: USAGE_RY:d-> asyncEvent.ry =值;休息;
情况用法:: USAGE_RZ:d-> asyncEvent.rz =值;休息;
}
休息;

案例用法:: USAGE_PAGE_BUTTON:
d-> asyncEvent.buttons [用法-1] =(值== 1);休息;
休息;
}

d-> asyncEvent.printOn(std :: cout);

}
}









到服务器....
服务器程序是..


#include< iostream>





#include"jmp_tcp/TcpServer.h"
#include"3d_connexion_poc/Protocol.h"
#include"cfsocket/CFTcpServer.h"

使用名称空间jmp_tcp;

class ServerTest:公共TcpServer
{

受保护的:

虚拟虚空handleConnection(int cfd)
{
char buff [256];

std :: cout<< 处理新的连接"<< std :: endl;
while(true)
{
std :: cout<< 新读"<< std :: endl;

bzero((char *)buff,sizeof(buff));
int length = recv(cfd,buff,sizeof(buff),0);
std :: cout<< "length"<<长度<< std :: endl;

如果(长度< = 0)中断;
其他
{
send(cfd,buff,length,0);
std :: cout<<增益<< std :: endl;
如果(strcmp(buff,"by")== 0)break;
}

}
std :: cout<< 终止连接"<< std :: endl;
}
};

void dynamicPort()
{
ServerTest服务器;
int端口= 8000;
while(!server.setup(port)&& port< 9000)
{
std :: cout<< std :: endl<< 端口的服务器设置失败"<<端口<< std :: endl;
port ++;
}

std :: cout<< std :: endl<< 服务器正在运行"<< std :: endl;
server.acceptConnections();
}

void staticPort()
{
ServerTest服务器;
int端口= 8000;
if(!server.setup(port))
{
std :: cout<< std :: endl<< 服务器设置失败"<< std :: endl;
返回;
}

std :: cout<< std :: endl<< 服务器正在运行"<< std :: endl;
server.acceptConnections();
}

无效testProtocol()
{
协议< int> p;
p.setElementValue("x",10);
p.setElementValue("y",23);
p.setElementValue("z",544);

p.printOn(std :: cout<< std :: endl);

int length = 0;
const char * frame = p.getBuffer(length);
p.setBuffer(frame,length);

p.printOn(std :: cout<< std :: endl);
}

无效testCFTcpServer()
{
CFTcpServer服务器;
int端口= 8000;
if(!server.setup(port))
{
std :: cout<< std :: endl<< 服务器设置失败"<< std :: endl;
返回;
}
std :: cout<< std :: endl<< 服务器正在运行"<< std :: endl;



CFRunLoopRun();
}

int main(int argc,char * const argv [])
{
//staticPort();
//dynamicPort();
//testProtocol();
testCFTcpServer();

返回0;
}


而客户端程序是..


i need to send an event to the server...
the event which i hav to send is...
d->asyncEvent.printOn(std::cout);
of the prog given below..

#include "Mouse3D.h"
#include "DevicesManager.h"
#include"Event.h"
#include <iostream>
using namespace hid;

namespace connexion_3d
{
const UInt32 Usage::MULTIAXIS_CONTROLLER_USAGE= 0x08;
const UInt32 Usage::PRIMARY_USAGE_PAGE= 0x01;
const UInt32 Usage::USAGE_PAGE_BUTTON= 0x09;
const UInt32 Usage::USAGE_X= 0x30;
const UInt32 Usage::USAGE_Y= 0x31;
const UInt32 Usage::USAGE_Z= 0x32;
const UInt32 Usage::USAGE_RX= 0x33;
const UInt32 Usage::USAGE_RY= 0x34;
const UInt32 Usage::USAGE_RZ= 0x35;
const UInt32 Usage::USAGE_PAGE_LED= 0x08;
const UInt32 Usage::USAGE_GENERIC_INDICATOR= 0x4B;

Usage::Usage():
txMin(0), txMax(0), rxMin(0), rxMax(0),
tyMin(0), tyMax(0), ryMin(0), ryMax(0),
tzMin(0), tzMax(0), rzMin(0), rzMax(0),
buttonsNumber(0)
{}




const unsigned int Mouse3D::QUEUE_SZ = 256;
const unsigned char Mouse3D::LED_ON = 0x01;
const unsigned char Mouse3D::LED_OFF = 0x00;
Mouse3D::Mouse3D(const IOHIDDeviceRef& _device):device(_device),usages(), queue(HIDDevice::makeQueue(_device, QUEUE_SZ)), valid(false), ledElement(NULL), isOpen(false), asyncEvent()
{
setup();
}

Mouse3D::~Mouse3D()
{
releaseQueue();
}

void Mouse3D:: releaseQueue()
{
if (queue)
{
IOHIDQueueStop(queue);
CFRelease(queue);
queue = NULL;
}
}

void Mouse3D::setup()
{
if (device && queue)
{
if (setupElements())
{
asyncEvent.buttons.resize(usages.buttonsNumber);
IOHIDQueueStart(queue);
valid = true;
}
}
}

void Mouse3D::open()
{
isOpen = true;
ledOn();
}

void Mouse3D::close()
{
isOpen = false;
ledOff();
}

unsigned short Mouse3D::buttonsNumber() const
{
return usages.buttonsNumber;
}

const Usage& Mouse3D::usage() const
{
return usages;
}

bool Mouse3D::ledOn() const
{
return writeOnLed(LED_ON);
}

bool Mouse3D::ledOff() const
{
return writeOnLed(LED_OFF);
}

bool Mouse3D::writeOnLed(unsigned char v) const
{
if (ledElement)
{
IOHIDValueRef vref = IOHIDValueCreateWithIntegerValue( kCFAllocatorDefault, ledElement, 0, v );
if ( vref )
{
IOReturn tIOReturn = IOHIDDeviceSetValue(device, ledElement, vref );
CFRelease( vref );
return kIOReturnSuccess == tIOReturn;
}
}
return false;
}

bool Mouse3D::setupElements()
{
CFArrayRef elements = IOHIDDeviceCopyMatchingElements( device, NULL, 0 );
if ( elements )
{
usages.buttonsNumber = 0;
CFIndex idx, cnt = CFArrayGetCount( elements );
for ( idx = 0; idx < cnt; idx++ )
{
IOHIDElementRef eref = ( IOHIDElementRef ) CFArrayGetValueAtIndex( elements, idx );
if ( eref )
{
if (!HIDIsValidElement(eref)) continue;

uint32_t usagePage = IOHIDElementGetUsagePage( eref );
uint32_t usage = IOHIDElementGetUsage( eref );

IOHIDElementType eleType = IOHIDElementGetType( eref );
if ( eleType == kIOHIDElementTypeOutput )
{
if (usagePage== Usage::USAGE_PAGE_LED && usage == Usage::USAGE_GENERIC_INDICATOR)
ledElement = eref;
}

if ( eleType > kIOHIDElementTypeInput_ScanCodes ) continue; // skip non-input element types


if ( !usagePage || !usage ) continue;
if ( -1 == usage ) continue;

//HIDDumpElementInfo(eref);
switch (usagePage)
{
case Usage::PRIMARY_USAGE_PAGE:
switch(usage)
{
case Usage::USAGE_X:
IOHIDQueueAddElement(queue, eref);
usages.txMin = IOHIDElementGetLogicalMin( eref );
usages.txMax = IOHIDElementGetLogicalMax( eref );
break;

case Usage::USAGE_Y:
IOHIDQueueAddElement(queue, eref);
usages.tyMin = IOHIDElementGetLogicalMin( eref );
usages.tyMax = IOHIDElementGetLogicalMax( eref );
break;

case Usage::USAGE_Z:
IOHIDQueueAddElement(queue, eref);
usages.tzMin = IOHIDElementGetLogicalMin( eref );
usages.tzMax = IOHIDElementGetLogicalMax( eref );
break;

case Usage::USAGE_RX:
IOHIDQueueAddElement(queue, eref);
usages.rxMin = IOHIDElementGetLogicalMin( eref );
usages.rxMax = IOHIDElementGetLogicalMax( eref );
break;

case Usage::USAGE_RY:
IOHIDQueueAddElement(queue, eref);
usages.ryMin = IOHIDElementGetLogicalMin( eref );
usages.ryMax = IOHIDElementGetLogicalMax( eref );
break;

case Usage::USAGE_RZ:
IOHIDQueueAddElement(queue, eref);
usages.rzMin = IOHIDElementGetLogicalMin( eref );
usages.rzMax = IOHIDElementGetLogicalMax( eref );
break;
}
break;

case Usage::USAGE_PAGE_BUTTON:
IOHIDQueueAddElement(queue, eref);
usages.buttonsNumber++;
break;
}
}
}
CFRelease(elements);
return true;
}
return false;
}


bool Mouse3D::read(Event3D& event) const
{
if (!(queue && device)) return false;

IOHIDValueRef vref = IOHIDQueueCopyNextValue(queue);
if (!vref) return false;
CFRelease(vref);

CFIndex value = IOHIDValueGetIntegerValue(vref);

IOHIDElementRef eref = IOHIDValueGetElement( vref );
if ( !eref ) return false;

uint32_t usagePage = IOHIDElementGetUsagePage( eref );
uint32_t usage = IOHIDElementGetUsage( eref );

if ( !usagePage || !usage ) return false;
if ( -1 == usage ) return false;

switch (usagePage)
{
case Usage::PRIMARY_USAGE_PAGE:
switch(usage)
{
case Usage::USAGE_X: event.tx = value; break;
case Usage::USAGE_Y: event.ty = value; break;
case Usage::USAGE_Z: event.tz = value; break;
case Usage::USAGE_RX: event.rx = value; break;
case Usage::USAGE_RY: event.ry = value; break;
case Usage::USAGE_RZ: event.rz = value; break;
}
break;

case Usage::USAGE_PAGE_BUTTON:
event.buttons[usage-1] = (value == 1); break;
break;
}
return true;
}

std::string Mouse3D::manufacturerString()
{
return HIDDevice::toStdString(IOHIDDevice_GetManufacturer(device));
}

std::string Mouse3D::productString()
{
return HIDDevice::toStdString(IOHIDDevice_GetProduct(device));
}

IOHIDDeviceRef Mouse3D::hidDevice()
{
return device;
}

void Mouse3D::hidDevice(IOHIDDeviceRef _device)
{
releaseQueue();

device = _device;
queue = HIDDevice::makeQueue(_device, QUEUE_SZ);
valid = false;
ledElement = NULL;

setup();
if (isOpen) open();
}

bool Mouse3D::isValid() const
{
return valid;
}

void Mouse3D::invalid()
{
valid = false;
}



void Mouse3D::deviceValueCallback( void * inContext, IOReturn inResult, void * inSender, IOHIDValueRef inIOHIDValueRef )
{
//#pragma unused( inSender )
IOHIDElementRef eref = IOHIDValueGetElement( inIOHIDValueRef );
if (!eref) return;



IOHIDDeviceRef tIOHIDDeviceRef = IOHIDElementGetDevice(eref);
if (!tIOHIDDeviceRef) return;

Mouse3D *d = ( Mouse3D* ) inContext;
if (!d) return;

std::cout << std::endl;

UInt32 usagePage = IOHIDElementGetUsagePage( eref );
UInt32 usage = IOHIDElementGetUsage( eref );

if ( !usagePage || !usage ) return;
if ( -1 == usage ) return;

//HIDDumpElementInfo(eref);
CFIndex value = IOHIDValueGetIntegerValue(inIOHIDValueRef);

switch(usagePage)
{
case Usage::PRIMARY_USAGE_PAGE:
switch(usage)
{
case Usage::USAGE_X: d->asyncEvent.tx = value; break;
case Usage::USAGE_Y: d->asyncEvent.ty = value; break;
case Usage::USAGE_Z: d->asyncEvent.tz = value; break;
case Usage::USAGE_RX: d->asyncEvent.rx = value; break;
case Usage::USAGE_RY: d->asyncEvent.ry = value; break;
case Usage::USAGE_RZ: d->asyncEvent.rz = value; break;
}
break;

case Usage::USAGE_PAGE_BUTTON:
d->asyncEvent.buttons[usage-1] = (value == 1); break;
break;
}

d->asyncEvent.printOn(std::cout);

}
}









to the server....
the server program is..


#include <iostream>





#include "jmp_tcp/TcpServer.h"
#include "3d_connexion_poc/Protocol.h"
#include "cfsocket/CFTcpServer.h"

using namespace jmp_tcp;

class ServerTest : public TcpServer
{

protected:

virtual void handleConnection(int cfd)
{
char buff[256];

std::cout << "handles a new connection" << std::endl;
while(true)
{
std::cout << " new read " << std::endl;

bzero((char *) buff, sizeof(buff));
int length = recv(cfd, buff, sizeof(buff), 0);
std::cout << " length " << length << std::endl;

if (length <=0) break;
else
{
send(cfd, buff, length, 0);
std::cout << buff << std::endl;
if (strcmp(buff, "by")==0) break;
}

}
std::cout << "terminate a connection" << std::endl;
}
};

void dynamicPort()
{
ServerTest server;
int port = 8000;
while(!server.setup(port) && port <9000)
{
std::cout << std::endl << "server setup failed for port "<< port << std::endl;
port++;
}

std::cout << std::endl << "server running" << std::endl;
server.acceptConnections();
}

void staticPort()
{
ServerTest server;
int port = 8000;
if(!server.setup(port))
{
std::cout << std::endl << "server setup failed"<< std::endl;
return;
}

std::cout << std::endl << "server running" << std::endl;
server.acceptConnections();
}

void testProtocol()
{
Protocol<int> p;
p.setElementValue("x", 10);
p.setElementValue("y", 23);
p.setElementValue("z",544);

p.printOn(std::cout << std::endl);

int length=0;
const char* frame = p.getBuffer(length);
p.setBuffer(frame, length);

p.printOn(std::cout << std::endl);
}

void testCFTcpServer()
{
CFTcpServer server;
int port = 8000;
if(!server.setup(port))
{
std::cout << std::endl << "server setup failed"<< std::endl;
return;
}
std::cout << std::endl << "server running"<< std::endl;



CFRunLoopRun();
}

int main (int argc, char * const argv[])
{
//staticPort();
//dynamicPort();
//testProtocol();
testCFTcpServer();

return 0;
}


and the client program is..


#include <iostream>
#include "jmp_tcp/TcpClient.h"
using namespace jmp_tcp;

int main (int argc, char * const argv[]) {
    TcpClient client;
    if(!client.connectByName("localhost", 8000))
    {
        std::cout << std::endl << "client connection failed"<< std::endl;
        return 0;
    }
    std::string msg;
    char buff[256];
    while(msg != "by")
    {
        std::cin >> msg;
        if(msg.length() >0)
        {
            bzero((char *) buff, sizeof(buff));
            if (!client.send(msg.c_str(), msg.length()))
            {
                std::cout<< std::endl << "send error";
                break;
            }
            int len = client.read(buff, sizeof(buff));
            std::cout << std::endl << len << " " << buff << std::endl;
            if (len <=0) break;
            else
            {
                std::cout << std::endl << len << " " << buff << std::endl;
            }
        }
    }
    client.disconnect();



返回0;
}


我应该如何链接..



return 0;
}


how should i link this..

推荐答案

Mouse3D *d = ( Mouse3D* ) inContext;
if (!d) return;


然后,您可以用文本填充std :: cout缓冲区,然后将其发送到服务器.

或者,您可以将* d设为全局变量,并以这种方式使用它.


Then you might fill the std::cout buffer with the text then send that to the server.

Or you might make *d a global varible, and work with it that way.


这篇关于TCP链接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-10 09:02