四、Mac与USB通讯IO框架

DeviceObject.h


[objc] view plain copy

    #import <Foundation/Foundation.h>  
    #include <IOKit/usb/IOUSBLib.h>  
    #include <IOKit/IOCFPlugIn.h>  

    @interface DeviceObject : NSObject  

    @property(nonatomic,assign)io_object_t              notification;  
    @property(nonatomic,assign)IOUSBInterfaceInterface  **interface;  
    @property(nonatomic,assign)UInt32                   locationID;  
    @property(nonatomic,assign)CFStringRef              deviceName;  

    @property(nonatomic,assign)IOUSBDeviceInterface     **dev;  
    @property(nonatomic,assign)UInt8                    pipeIn;  
    @property(nonatomic,assign)UInt8                    pipeOut;  
    @property(nonatomic,assign)UInt16                   maxPacketSizeIn;  
    @property(nonatomic,assign)UInt16                   maxPacketSizeOut;  

    @end  
DeviceObject.m


[objc] view plain copy

    #import "DeviceObject.h"  

    @implementation DeviceObject  

    @synthesize notification;  
    @synthesize interface;  
    @synthesize locationID;  
    @synthesize deviceName;  

    @synthesize dev;  
    @synthesize pipeIn;  
    @synthesize pipeOut;  
    @synthesize maxPacketSizeIn;  
    @synthesize maxPacketSizeOut;  

    @end  
UsbMonitor.h


[objc] view plain copy

    #import <Foundation/Foundation.h>  
    #include <IOKit/IOKitLib.h>  
    #include <IOKit/IOMessage.h>  
    #include <IOKit/IOCFPlugIn.h>  
    #include <IOKit/usb/IOUSBLib.h>  
    #import "DeviceObject.h"  

    @protocol UsbMonitorDelegate <NSObject>  
    @optional  
    - (void)usbDidPlunIn:(DeviceObject*)usbObject;  
    - (void)usbDidRemove:(DeviceObject*)usbObject;  
    @end  

    @interface UsbMonitor : NSObject {  
    }  

    @property(nonatomic,strong)NSMutableArray* arrayDevices;  
    @property(nonatomic,strong)id<UsbMonitorDelegate> delegate;  

    + (UsbMonitor *)sharedUsbMonitorManager;  
    - (id)initWithVID:(long)vid withPID:(long)pid;  
    - (id)initWithVID:(long)vid withPID:(long)pid withDelegate:(id<UsbMonitorDelegate>)gate;  
    - (DeviceObject*)getObjectByID:(long)localid;  
    - (IOReturn)WriteSync:(DeviceObject*)pDev buffer:(char*) writeBuffer size:(unsigned int)size;  
    - (IOReturn)WriteAsync:(DeviceObject*)pDev buffer:(char*)writeBuffer size:(unsigned int)size;  
    - (IOReturn)ReadSync:(DeviceObject*)pDev buffer:(char*)buff size:(unsigned int)size;  
    - (IOReturn)ReadAsync:(DeviceObject*)pDev buffer:(char*)buff size:(unsigned int)size;  
    - (NSMutableArray*)getDeviceArray;  

    @end 
UsbMonitor.m


[objc] view plain copy

    #import "UsbMonitor.h"  

    @implementation UsbMonitor  

    @synthesize arrayDevices;  
    @synthesize delegate;  

    static UsbMonitor *sharedInstance = nil;  

    IONotificationPortRef   gNotifyPort;  
    io_iterator_t           gAddedIter;  
    CFRunLoopRef            gRunLoop;  


    void SignalHandler(int sigraised) {  
        fprintf(stderr, "\nInterrupted.\n");  
        exit(0);  
    }  

    void DeviceNotification(voidvoid *refCon, io_service_t service, natural_t messageType, voidvoid *messageArgument) {  
        kern_return_t   kr;  
        DeviceObject    *privateDataRef = (__bridge DeviceObject *) refCon;  

        if (messageType == kIOMessageServiceIsTerminated) {  
            for (DeviceObject* usbObj in [UsbMonitor sharedUsbMonitorManager].arrayDevices) {  
                if (usbObj.locationID == privateDataRef.locationID) {  
                    NSLog(@"delete id=%08x",usbObj.locationID);  
                    [[UsbMonitor sharedUsbMonitorManager].arrayDevices removeObject:usbObj];  
                    break;  
                }  
            }  

            if ([[UsbMonitor sharedUsbMonitorManager].delegate respondsToSelector:@selector(usbDidRemove:)]) {  
                [[UsbMonitor sharedUsbMonitorManager].delegate usbDidRemove:privateDataRef];  
            }  

            CFRelease(privateDataRef.deviceName);  

            if (privateDataRef.interface) {  
                (*(privateDataRef.interface))->USBInterfaceClose(privateDataRef.interface);  
                (*(privateDataRef.interface))->Release(privateDataRef.interface);  
            }  

            if (privateDataRef.dev) {  
                (*(privateDataRef.dev))->USBDeviceClose(privateDataRef.dev);  
                kr = (*privateDataRef.dev)->Release(privateDataRef.dev);  
            }  

            kr = IOObjectRelease(privateDataRef.notification);  
        }  
    }  

    void DeviceAdded(voidvoid *refCon, io_iterator_t iterator) {  
        kern_return_t       kr;  
        io_service_t        usbDevice;  
        IOCFPlugInInterface **plugInInterface = NULL;  
        SInt32              score;  
        HRESULT             res;  

        while ((usbDevice = IOIteratorNext(iterator))) {  
            io_name_t       deviceName;  
            CFStringRef     deviceNameAsCFString;  
            DeviceObject    *privateDataRef = [[DeviceObject alloc]init];  
            UInt32          locationID;  

            kr = IORegistryEntryGetName(usbDevice, deviceName);  
            if (KERN_SUCCESS != kr) {  
                deviceName[0] = '\0';  
            }  

            deviceNameAsCFString = CFStringCreateWithCString(kCFAllocatorDefault,deviceName,kCFStringEncodingASCII);  
            //NSLog(@"deviceName:%@",deviceNameAsCFString);  

            privateDataRef.deviceName = deviceNameAsCFString;  
            kr = IOCreatePlugInInterfaceForService(usbDevice,kIOUSBDeviceUserClientTypeID, kIOCFPlugInInterfaceID,&plugInInterface, &score);  

            if ((kIOReturnSuccess != kr) || !plugInInterface) {  
                NSLog(@"IOCreatePlugInInterfaceForService returned 0x%08x.",kr);  
                continue;  
            }  

            IOUSBDeviceInterface     **oneDev = NULL;  
            res = (*plugInInterface)->QueryInterface(plugInInterface, CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID),(LPVOID*)&oneDev);  
            privateDataRef.dev = oneDev;  

            (*plugInInterface)->Release(plugInInterface);  
            if (res || privateDataRef.dev == NULL) {  
                NSLog(@"QueryInterface returned %d.\n", (int)res);  
                continue;  
            }  

            kr = (*privateDataRef.dev)->GetLocationID(privateDataRef.dev, &locationID);  
            if (KERN_SUCCESS != kr) {  
                NSLog(@"GetLocationID returned 0x%08x.\n", kr);  
                continue;  
            } else {  
                NSLog(@"Location ID: 0x%08x", locationID);  
            }  
            privateDataRef.locationID = locationID;  

            kr = (*privateDataRef.dev)->USBDeviceOpen(privateDataRef.dev);  
            if(kr != kIOReturnSuccess) {  
                NSLog(@"Usb Open Fail!");  
                (*privateDataRef.dev)->USBDeviceClose(privateDataRef.dev);  
                (void) (*privateDataRef.dev)->Release(privateDataRef.dev);  
                privateDataRef.dev = NULL;  
                continue;  
            }  

            //configure device  
            UInt8                numConfig;  
            IOUSBConfigurationDescriptorPtr configDesc;  

            //Get the number of configurations.  
            kr = (*privateDataRef.dev)->GetNumberOfConfigurations(privateDataRef.dev, &numConfig);  
            if(numConfig == 0)  
                continue;  

            //Get the configuration descriptor for index 0  
            kr = (*privateDataRef.dev)->GetConfigurationDescriptorPtr(privateDataRef.dev, 0, &configDesc);  
            if(kr != kIOReturnSuccess) {  
                NSLog(@"Unable to get configuration descriptor for index 0 (err = %08x)\n",kr);  
                continue;  
            }  
            kr = [[UsbMonitor sharedUsbMonitorManager] FindUSBInterface:privateDataRef];  
            if (kr != kIOReturnSuccess) {  
                NSLog(@"Interface Open Fail!");  
                (*privateDataRef.dev)->USBDeviceClose(privateDataRef.dev);  
                (*privateDataRef.dev)->Release(privateDataRef.dev);  
                privateDataRef.dev = NULL;  
                continue ;  
            }  

            io_object_t              oneIter;  
            kr = IOServiceAddInterestNotification(gNotifyPort,usbDevice,kIOGeneralInterest, DeviceNotification,(__bridge void*)privateDataRef,&oneIter);  
            privateDataRef.notification = oneIter;  

            if (KERN_SUCCESS != kr) {  
                NSLog(@"IOServiceAddInterestNotification returned 0x%08x", kr);  
            }  

            kr = IOObjectRelease(usbDevice);  
        }  
    }  

    void usbMonitorCallBack(voidvoid *refcon, IOReturn result, voidvoid *arg0) {  
        if (result == kIOReturnSuccess && refcon) {  
            //u32 *pLen = (u32 *)refcon;  
            //*pLen = reinterpret_cast<long>arg0;  
        }  
        NSLog(@"read and write callback!");  
        CFRunLoopStop(CFRunLoopGetCurrent());  
    }  


    + (UsbMonitor *)sharedUsbMonitorManager {  
        static dispatch_once_t onceToken;  
        dispatch_once(&onceToken, ^{  
            if (sharedInstance == nil)  
                sharedInstance = [(UsbMonitor *)[super allocWithZone:NULL] init];  
        });  
        return sharedInstance;  
    }  

    + (id)allocWithZone:(NSZone *)zone {  
        return [self sharedUsbMonitorManager];  
    }  

    - (id)copyWithZone:(NSZone *)zone {  
        return self;  
    }  

    - (id)initWithVID:(long)vid withPID:(long)pid {  
        self = [super init];  
        if (self) {  
            arrayDevices = [NSMutableArray new];  

            CFMutableDictionaryRef  matchingDict;  
            CFRunLoopSourceRef      runLoopSource;  
            CFNumberRef             numberRef;  
            kern_return_t           kr;  
            long                    usbVendor = vid;  
            long                    usbProduct = pid;  

            matchingDict = IOServiceMatching(kIOUSBDeviceClassName);  
            if (matchingDict == NULL) {  
                return nil;  
            }  

            numberRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &usbVendor);  
            CFDictionarySetValue(matchingDict,CFSTR(kUSBVendorID),numberRef);  
            CFRelease(numberRef);  

            numberRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &usbProduct);  
            CFDictionarySetValue(matchingDict,CFSTR(kUSBProductID),numberRef);  
            CFRelease(numberRef);  
            numberRef = NULL;  

            gNotifyPort = IONotificationPortCreate(kIOMasterPortDefault);  
            runLoopSource = IONotificationPortGetRunLoopSource(gNotifyPort);  

            gRunLoop = CFRunLoopGetCurrent();  
            CFRunLoopAddSource(gRunLoop, runLoopSource, kCFRunLoopDefaultMode);  

            kr = IOServiceAddMatchingNotification(gNotifyPort,kIOFirstMatchNotification,matchingDict,DeviceAdded,NULL,&gAddedIter);  

            DeviceAdded(NULL, gAddedIter);  

            CFRunLoopRun();  

        }  
        return self;  
    }  

    - (id)initWithVID:(long)vid withPID:(long)pid withDelegate:(id<UsbMonitorDelegate>)gate {  
        self = [super init];  
        if (self) {  
            arrayDevices = [NSMutableArray new];  

            CFMutableDictionaryRef  matchingDict;  
            CFRunLoopSourceRef      runLoopSource;  
            CFNumberRef             numberRef;  
            kern_return_t           kr;  
            long                    usbVendor = vid;  
            long                    usbProduct = pid;  
            delegate = gate;  
    //        sig_t                 oldHandler;  
    //          
    //        oldHandler = signal(SIGINT, SignalHandler);  
    //        if (oldHandler == SIG_ERR) {  
    //            fprintf(stderr, "Could not establish new signal handler.");  
    //        }  

            matchingDict = IOServiceMatching(kIOUSBDeviceClassName);  
            if (matchingDict == NULL) {  
                return nil;  
            }  

            numberRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &usbVendor);  
            CFDictionarySetValue(matchingDict,CFSTR(kUSBVendorID),numberRef);  
            CFRelease(numberRef);  

            numberRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &usbProduct);  
            CFDictionarySetValue(matchingDict,CFSTR(kUSBProductID),numberRef);  
            CFRelease(numberRef);  
            numberRef = NULL;  

            gNotifyPort = IONotificationPortCreate(kIOMasterPortDefault);  
            runLoopSource = IONotificationPortGetRunLoopSource(gNotifyPort);  

            gRunLoop = CFRunLoopGetCurrent();  
            CFRunLoopAddSource(gRunLoop, runLoopSource, kCFRunLoopDefaultMode);  

            kr = IOServiceAddMatchingNotification(gNotifyPort,kIOFirstMatchNotification,matchingDict,DeviceAdded,NULL,&gAddedIter);  

            DeviceAdded(NULL, gAddedIter);  

            CFRunLoopRun();  

        }  
        return self;  
    }  

    -(void)dealloc {  
        for (DeviceObject* dev in arrayDevices) {  
            (*(dev.interface))->USBInterfaceClose(dev.interface);  
            (*(dev.interface))->Release(dev.interface);  
            (*(dev.dev))->USBDeviceClose(dev.dev);  
            (*(dev.dev))->Release(dev.dev);  
        }  
        [arrayDevices removeAllObjects];  
    }  

    -(IOReturn) FindUSBInterface:(DeviceObject*)usbObject {  
        IOReturn                        kr = kIOReturnError;  
        IOUSBFindInterfaceRequest       request;  
        io_iterator_t                   iterator;  
        io_service_t                    usbInterface;  
        IOCFPlugInInterface             **plugInInterface = NULL;  
        IOUSBInterfaceInterface         **interface = NULL;  
        HRESULT                         result;  
        SInt32                          score;  
        UInt8                           interfaceNumEndpoints;  
        UInt8                           pipeRef;  
        UInt16                          maxPacketSize = 0;  
        UInt8                           pipeIn = 0xff;  
        UInt8                           pipeOut = 0xff;  
        UInt16                          maxPacketSizeIn = 0;  
        UInt16                          maxPacketSizeOut = 0;  

        //Iterate all usb interface  
        request.bInterfaceClass = kIOUSBFindInterfaceDontCare;  
        request.bInterfaceSubClass = kIOUSBFindInterfaceDontCare;  
        request.bInterfaceProtocol = kIOUSBFindInterfaceDontCare;  
        request.bAlternateSetting = kIOUSBFindInterfaceDontCare;  

        //Get an iterator for the interfaces on the device  
        kr = (*usbObject.dev)->CreateInterfaceIterator(usbObject.dev, &request, &iterator);  
        if(kr != kIOReturnSuccess) {  
            NSLog(@"Unable to CreateInterfaceIterator %08x\n", kr);  
            return kr;  
        }  

        kr = kIOReturnError;  
        while((usbInterface = IOIteratorNext(iterator))) {  
            pipeIn = 0xff;  
            pipeOut = 0xff;  
            kr = IOCreatePlugInInterfaceForService(usbInterface,                                               kIOUSBInterfaceUserClientTypeID, kIOCFPlugInInterfaceID,                                               &plugInInterface, &score);  
            kr = IOObjectRelease(usbInterface);  
            if(kr != kIOReturnSuccess || !plugInInterface) {  
                NSLog(@"Unable to create a plug-in (%08x)\n", kr);  
                break;  
            }  

            result = (*plugInInterface)->QueryInterface(plugInInterface,                           CFUUIDGetUUIDBytes(kIOUSBInterfaceInterfaceID), (LPVOIDLPVOID *)&interface);  
            IODestroyPlugInInterface(plugInInterface);  
            if(result || !interface) {  
                NSLog(@"Unable to create a interface for the device interface %08x\n",(int)result);  
                break;  
            }  
            //kr = (*interface)->USBInterfaceClose(interface);  
            kr = (*interface)->USBInterfaceOpen(interface);  
            if(kr != kIOReturnSuccess) {  
                NSLog(@"Unable to open interface for the device interface %08x\n", kr);  
                (*interface)->USBInterfaceClose(interface);  
                (void) (*interface)->Release(interface);  
                interface = NULL;  
                break;  
            }  
            kr = (*interface)->GetNumEndpoints(interface, &interfaceNumEndpoints);  
            if(kr != kIOReturnSuccess) {  
                (void) (*interface)->USBInterfaceClose(interface);  
                (void) (*interface)->Release(interface);  
                interface = NULL;  
                break;  
            }  
            for(pipeRef = 1; pipeRef <= interfaceNumEndpoints; pipeRef++) {  
                IOReturn     kr2;  
                UInt8        direction;  
                UInt8        number;  
                UInt8        transferType;  
                UInt8        interval;  

                kr2 = (*interface)->GetPipeProperties(interface, pipeRef, &direction,&number, &transferType, &maxPacketSize, &interval);  
                if(kr2 != kIOReturnSuccess) {  
                    NSLog(@"Unable to get properties of pipe %d (%08x)\n",pipeRef, kr2);  
                } else {  
                    if(transferType == kUSBBulk) {  
                        if(direction == kUSBIn) {  
                            pipeIn = pipeRef;  
                            maxPacketSizeIn = maxPacketSize;  
                        }  
                        else if(direction == kUSBOut) {  
                            pipeOut = pipeRef;  
                            maxPacketSizeOut = maxPacketSize;  
                        }  
                    }  
                }  
            }  
            if (pipeIn != 0xff && pipeOut != 0xff) {  
                usbObject.interface = interface;  
                usbObject.pipeIn = pipeIn;  
                usbObject.pipeOut = pipeOut;  
                usbObject.maxPacketSizeIn = maxPacketSizeIn;  
                usbObject.maxPacketSizeOut = maxPacketSizeOut;  
                BOOL isIn = NO;  
                for (DeviceObject* obj in arrayDevices) {  
                    if (obj.locationID == usbObject.locationID) {  
                        isIn = YES;  
                        break ;  
                    }  
                }  
                if (!isIn) {  
                    [arrayDevices addObject:usbObject];  
                }  
                if ([delegate respondsToSelector:@selector(usbDidPlunIn:)]) {  
                    [delegate usbDidPlunIn:usbObject];  
                }  
                return kIOReturnSuccess;  
            }  
            (*interface)->USBInterfaceClose(interface);  
            (*interface)->Release(interface);  
            interface = NULL;  
        }  
        return kr;  
    }  

    - (DeviceObject*)getObjectByID:(long)localid {  
        for (DeviceObject* obj in arrayDevices) {  
            if (obj.locationID == localid) {  
                return obj;  
            }  
        }  
        return nil;  
    }  

    //同步  
    -(IOReturn)WriteSync:(DeviceObject*)pDev buffer:(char*) writeBuffer size:(unsigned int)size  
    {  
        if (pDev && pDev.interface) {  
            if(size <= pDev.maxPacketSizeOut) {  
                return [self WriteAsync:pDev buffer:writeBuffer size:size];  
            }  
            kern_return_t kr = 0;  
            charchar *tmp = writeBuffer;  
            unsigned int nWrite = (size > pDev.maxPacketSizeOut ? pDev.maxPacketSizeOut : size);  
            unsigned int nLeft = size;  
            while(1) {  
                if((int)nLeft <= 0) {  
                    break;  
                }  
                kr = (*(pDev.interface))->WritePipe(pDev.interface,pDev.pipeOut, (voidvoid *)tmp, nWrite);  
                if(kr != kIOReturnSuccess)  
                    break;  
                tmp += nWrite;  
                nLeft -= nWrite;  
                nWrite = (nLeft > pDev.maxPacketSizeOut ? pDev.maxPacketSizeOut : nLeft);  
            }  
            return kr;  
        }  

        return kIOReturnNoDevice;  
    }  

    //异步  
    -(IOReturn)WriteAsync:(DeviceObject*)pDev buffer:(char*)writeBuffer size:(unsigned int)size {  
        if (pDev == nil||pDev.interface == nil) {  
            return kIOReturnNoDevice;  
        }  

        IOReturn                  err;  
        CFRunLoopSourceRef        cfSource;  
        unsigned int*             pWrite;  

        err = (*(pDev.interface))->CreateInterfaceAsyncEventSource(pDev.interface, &cfSource);  
        if (err) {  
            NSLog(@"transferData: unable to create event source, err = %08x\n", err);  
            return err;  
        }  
        CFRunLoopAddSource(CFRunLoopGetCurrent(), cfSource, kCFRunLoopDefaultMode);  

        err = (*(pDev.interface))->WritePipeAsync(pDev.interface, pDev.pipeOut, (voidvoid *)writeBuffer, size,                                         (IOAsyncCallback1)usbMonitorCallBack, (void*)pWrite);  
        if (err != kIOReturnSuccess) {  
            NSLog(@"transferData: WritePipeAsyncFailed, err = %08x\n", err);  
            CFRunLoopRemoveSource(CFRunLoopGetCurrent(), cfSource, kCFRunLoopDefaultMode);  
            *pWrite = 0;  
            return err;  
        }  

        CFRunLoopRun();  
        CFRunLoopRemoveSource(CFRunLoopGetCurrent(), cfSource, kCFRunLoopDefaultMode);  

        return err;  
    }  

    -(IOReturn)ReadSync:(DeviceObject*)pDev buffer:(char*)buff size:(unsigned int)size {  
        if (pDev && pDev.interface) {  
            if(sizeof(buff) <= pDev.maxPacketSizeIn) {  
                return [self ReadAsync:pDev buffer:buff size:size];  
            }  
            kern_return_t kr = 0;  
            UInt32 nRead = pDev.maxPacketSizeIn;  
            unsigned int nLeft = size;  
            charchar *tmp = (charchar *)buff;  

            while(1) {  
                if((int)nLeft <= 0)  
                    break;  

                kr = (*(pDev.interface))->ReadPipe(pDev.interface,                   pDev.pipeIn, (voidvoid *)tmp, &nRead);  
                if(kr != kIOReturnSuccess) {  
                    printf("transferData: Readsync Failed, err = %08x\n", kr);  
                    break;  
                }  

                tmp += nRead;  
                nLeft -= nRead;  
                nRead = pDev.maxPacketSizeIn;  
            }  
            int nRet = ((int)nLeft > 0 ? nLeft : 0);  
            size = size - nRet;  
            return kr;  
        }  
        return kIOReturnNoDevice;  
    }  

    -(IOReturn)ReadAsync:(DeviceObject*)pDev buffer:(char*)buff size:(unsigned int)size {  
        if (pDev == nil||pDev.interface == nil) {  
            return kIOReturnNoDevice;  
        }  

        IOReturn                    err;  
        CFRunLoopSourceRef          cfSource;  
        unsigned int*               pRead;  

        err = (*(pDev.interface))->CreateInterfaceAsyncEventSource(pDev.interface, &cfSource);  
        if (err) {  
            NSLog(@"transferData: unable to create event source, err = %08x\n", err);  
            return err;  
        }  
        CFRunLoopAddSource(CFRunLoopGetCurrent(), cfSource, kCFRunLoopDefaultMode);  

        err = (*(pDev.interface))->ReadPipeAsync(pDev.interface, pDev.pipeIn, buff, size,(IOAsyncCallback1)usbMonitorCallBack, (void*)pRead);  
        if (err != kIOReturnSuccess) {  
            NSLog(@"transferData: size %u, ReadAsyncFailed, err = %08x\n", size, err);  
            CFRunLoopRemoveSource(CFRunLoopGetCurrent(), cfSource, kCFRunLoopDefaultMode);  
            pRead = nil;  
            pDev = nil;  
            return err;  
        }  

        CFRunLoopRun();  
        CFRunLoopRemoveSource(CFRunLoopGetCurrent(), cfSource, kCFRunLoopDefaultMode);  

        return err;  
    }  

    - (NSMutableArray*)getDeviceArray {  
        return arrayDevices;  
    }  

    @end  
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是一个基于t-io框架实现即时通讯的示例代码: ```java public class ChatServer { public static void main(String[] args) throws Exception { TioServer server = new TioServer(new ChatServerListener()); server.start("0.0.0.0", 8888); } private static class ChatServerListener extends ServerTioConfigAdapter { @Override public void init(ChannelContext channelContext) throws Exception { // 设置心跳超时时间为60秒 channelContext.setHeartbeatTimeout(60); } @Override public void onAfterConnected(ChannelContext channelContext, boolean isConnected, boolean isReconnect) throws Exception { String clientIp = channelContext.getClientNode().getIp(); System.out.println("客户端 " + clientIp + " 已连接"); } @Override public void onAfterReceived(ChannelContext channelContext, Packet packet, int packetSize) throws Exception { // 接收到消息时的处理逻辑 ChatPacket chatPacket = (ChatPacket) packet; String message = chatPacket.getMessage(); System.out.println("收到来自 " + channelContext.getClientNode().getIp() + " 的消息:" + message); // 将消息广播给所有连接的客户端 Tio.sendToAll(channelContext.getGroupContext(), chatPacket); } @Override public void onAfterClose(ChannelContext channelContext, Throwable throwable, String remark, boolean isRemove) throws Exception { String clientIp = channelContext.getClientNode().getIp(); System.out.println("客户端 " + clientIp + " 已断开连接"); } } private static class ChatPacket extends Packet { private String message; public ChatPacket(String message) { this.message = message; } @Override public byte[] encode() { return message.getBytes(); } @Override public void decode(byte[] bytes) { message = new String(bytes); } public String getMessage() { return message; } } } ``` 该示例代码实现了一个简单的聊天服务器,客户端与服务器之间通过t-io框架实现即时通讯。在服务器端,我们使用`ChatServerListener`类作为`t-io`的服务端配置适配器,处理客户端连接、断开连接和接收消息等事件。在客户端每次发送消息时,我们将消息封装为`ChatPacket`对象并广播给所有连接的客户端。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值