import 'dart:async'; import 'package:semaphore/semaphore.dart'; import 'dart:io'; import 'dart:convert'; void main() async{ List a = ['zizi.cn','wuwu.cn','baba.cn','hehe.cn','mama.cn','ququ.cn','kaka.cn','yuyu.cn','sasa.cn','sisi.cn','bubu.cn']; String host = 'whois.cnnic.net.cn'; int port = 43; var maxCount = 1; var sm = LocalSemaphore(maxCount); List<Future> whoisToDoList = []; for(int i=0; i<a.length; i++){ DomainModel dm = DomainModel(domain: a[i], server: host, port: port, status: Status.pending, dataFinished:false); whoisToDoList.add(doWork(sm, dm)); } await Future.wait(whoisToDoList); print('finished'); } Future doWork(LocalSemaphore sm, DomainModel dm)async{ try { await sm.acquire(); Whois w = Whois(domain: dm); await w.getWhois(); } finally{ await sm.release(); } } enum Status { pending, checking, done, } class DomainModel{ DomainModel({this.domain, this.server, this.port, this.status, this.dataFinished}); String domain; String server; int port; Status status; bool dataFinished; String whois; } class Whois { Whois({this.domain}); DomainModel domain; int i = 0; Socket socket; Future getWhois()async{ await request(); while(domain.status != Status.done){ await Future.delayed(Duration(milliseconds:100)); } } Future request() async{ print('1. starting ${domain.domain}'); socket = await Socket.connect(domain.server, domain.port); await socket.listen(onData, onDone: onDone, onError: onError); socket.write(domain.domain + ' '); } Future onData(value)async{ domain.dataFinished = true; await Future.delayed(Duration(seconds: 1)); var data = utf8.decode(value); domain.whois = data; } Future onDone () async{ dispose(); i = i + 1; if(domain.dataFinished == false){ print('3. ${domain.domain} failed times: $i, will wait for 1 seconds to restart'); await Future.delayed(Duration(seconds: 1)); print('4. ${domain.domain} restart'); await request(); }else{ print('set status as done'); domain.status = Status.done; } } onError(e){ print('${domain.domain} error'); } dispose(){ print('${domain.domain} socket destroyed'); socket.destroy(); } }