80,337
社区成员
发帖
与我相关
我的任务
分享
#pragma once
#include "thread.h"
#include <string>
#include <vector>
class ISocketCallback {
public:
virtual void OnBind(thread* owner, int code) = 0; //request by server only. //0: success; else SOCKET_ERROR;
virtual void OnAccept(thread* owner, thread* socket) = 0; //request by server only. //note: you may also invoke socket->SetCallback() to listen it.
virtual void OnDisaccept(thread* owner, thread* socket, int code) = 0; //request by server only. //0: success; else SOCKET_ERROR;
virtual void OnConnect(thread* owner, int code) = 0; //request by client only. //0: success; else SOCKET_ERROR;
virtual void OnClose(thread* owner, int code) = 0; //request by server & client both. //0: success; else SOCKET_ERROR;
virtual void OnReceive(thread* owner, thread* socket, const char* data, int len) = 0; //request by server & client both. //note: the owner is client
};
class CServerSocketThread: public thread {
public:
CServerSocketThread();
virtual ~CServerSocketThread();
void SetCallback(ISocketCallback* callback);
bool Bind(int port);
void Close();
int Send(thread* socket, const char* data, int len); //send to the special socket or all connected sockets if null
void DoReceive(thread* socket, const char* data, int len); //invoked by client
void DoClose(thread* socket, int code); //invoked by client
protected:
virtual void OnExecute();
private:
ISocketCallback* m_callback;
int m_port;
std::vector<thread*> m_clients;
CRITICAL_SECTION m_cs;
};
class CClientSocketThread: public thread {
public:
CClientSocketThread();
virtual ~CClientSocketThread();
void SetCallback(ISocketCallback* callback);
std::string GetAddress();
bool Accept(SOCKET socket, thread* parent);
bool Connect(const wchar_t* addr, int port);
void Close();
int Send(const char* data, int len);
protected:
virtual void OnExecute();
private:
//for both accept or connect. but usually connect
ISocketCallback* m_callback;
//for accept
SOCKET m_socket;
thread* m_parent;
//for connect
std::wstring m_addr;
int m_port;
//CRITICAL_SECTION m_cs;
};
package com.android_daemon.service;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.util.ArrayList;
interface ISocketCallback {
public void onBind(Thread owner, int code); //request by server only. //0: success; else SOCKET_ERROR;
public void onAccept(Thread owner, Thread socket); //request by server only. //note: you may also invoke socket->SetCallback() to listen it.
public void onDisaccept(Thread owner, Thread socket, int code); //request by server only. //0: success; else SOCKET_ERROR;
public void onConnect(Thread owner, int code); //request by client only. //0: success; else SOCKET_ERROR;
public void onClose(Thread owner, int code); //request by server & client both. //0: success; else SOCKET_ERROR;
public void onReceive(Thread owner, Thread socket, byte[] data, int len); //request by server & client both. //note: the owner is client
};
class ServerSocketThread extends Thread {
volatile boolean _stop = false;
private ISocketCallback callback = null;
private int port = 0;
private java.util.List<Thread> clients = null;
public ServerSocketThread() {
clients = new ArrayList<Thread>();
}
public void setCallback(ISocketCallback callback) {
this.callback = callback;
}
public void bind(int port) {
close();
_stop = false;
this.port = port;
}
public void close() {
_stop = true;
//interrupt();
try {
join();
}
catch (InterruptedException e) {
}
port = 0;
synchronized (ServerSocketThread.class) {
clients.clear();
}
}
public void send(Thread socket, byte[] data, int len) { //send to the special socket or all connected sockets if null
if(socket != null)
((ClientSocketThread)socket).send(data, len);
else {
synchronized (ServerSocketThread.class) {
for (Thread client : clients) {
if(client == null)
continue;
ClientSocketThread thread = (ClientSocketThread)client;
thread.send(data, len);
}
}
}
}
public void doReceive(Thread socket, byte[] data, int len) { //invoked by client
if(callback != null)
callback.onReceive(this, socket, data, len);
}
public void doClose(Thread socket, int code) { //invoked by client
//fixme: to be optimized: when thread run out, the thread object is also in the clients. as so reason--1:occupy more resource; 2:there will send to some invalid socket which has been closed.
if(callback != null)
callback.onDisaccept(this, socket, code);
}
public void run() {
try {
/*************************************
fd_set fdread;
timeval timeout;
timeout.tv_sec = 1;
timeout.tv_usec = 0;
while(true) {
FD_ZERO(&fdread);
FD_SET(sockSrv, &fdread);
if(select(0, &fdread, 0, 0, &timeout) > 0 && FD_ISSET(sockSrv, &fdread)) {
SOCKET client = accept(sockSrv, 0, 0);
}
}
*************************************/
ServerSocket server = new ServerSocket(this.port);
if(callback != null)
callback.onBind(this, server != null ? 0 : -1);
System.out.println("server.bind()-------------------");
server.setSoTimeout(1000);
while (!_stop && !server.isClosed()) {
try {
Socket socket = server.accept();
System.out.println("server.accept()------------------" + socket.getInetAddress().getHostAddress() + ":" + socket.getLocalPort());
ClientSocketThread thread = new ClientSocketThread();
thread.accept(socket, this);
thread.start();
synchronized (ServerSocketThread.class) {
clients.add(thread);
}
if(callback != null)
callback.onAccept(this, thread);
}
catch (SocketTimeoutException e) {
}
}
synchronized (ServerSocketThread.class) {
for (Thread client : clients) {
if(client == null)
continue;
ClientSocketThread thread = (ClientSocketThread)client;
thread.close();
}
clients.clear();
}
server.close();
if(callback != null)
callback.onClose(this, server != null ? 0 : -1);
System.out.println("server.close()-------------------");
}
catch (IOException e) {
e.printStackTrace();
}
}
}
class ClientSocketThread extends Thread {
volatile boolean _stop = false;
//for both accept or connect. but usually connect
private ISocketCallback callback = null;
//for accept
private Socket socket = null;
private Thread parent = null;
//for connect
private String addr = "";
private int port = 0;
public ClientSocketThread() {
}
public void setCallback(ISocketCallback callback) {
this.callback = callback;
}
public String getAddress() {
if(socket == null)
return "";
return socket.getInetAddress().getHostAddress();
}
public void accept(Socket socket, Thread parent) {
close();
_stop = false;
this.socket = socket;
this.parent = parent;
}
public void connect(String addr, int port) {
close();
_stop = false;
this.addr = addr;
this.port = port;
}
public void close() {
_stop = true;
//interrupt();
try {
join();
}
catch (InterruptedException e) {
}
port = 0; //maybe mistake in mac because of join
socket = null;
parent = null;
}
public void send(byte[] data, int len) {
//synchronized (ClientSocketThread.class) {
try {
socket.getOutputStream().write(data, 0, len);
socket.getOutputStream().flush();
// 由系统标准输入输出设备构造BufferedReader,PrintWriter对象
// BufferedReader sysin = new BufferedReader(new InputStreamReader(System.in));
// PrintWriter sysout = new PrintWriter(System.out);
// 由Socket对象得到输出流构造BufferedReader,PrintWriter对象
// BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
// PrintWriter out = new PrintWriter(client.getOutputStream());
//PrintWriter out = new PrintWriter(client.getOutputStream());
//out.println(data);
//out.flush();
}
catch (IOException e) {
}
//}
}
public void run() {
try {
if(socket == null) { //for connect
socket = new Socket(addr, port);
if(callback != null)
callback.onConnect(this, socket != null ? 0 : -1);
System.out.println("client.connect()-------------------");
}
/*************************************
fd_set fdread;
timeval timeout;
timeout.tv_sec = 1;
timeout.tv_usec = 0;
while(true) {
FD_ZERO(&fdread);
FD_SET(client, &fdread);
if(select(0, &fdread, 0, 0, &timeout) > 0 && FD_ISSET(client, &fdread)) {
char buf[1024];
recv(client, buf, 1024, 0);
}
}
*************************************/
socket.setSoTimeout(1000);
byte[] buf = new byte[1048776]; //1024 * 1024 + 200
//Arrays.fill(buf, (byte) 0);
while (!_stop && !socket.isClosed()) {
try {
//synchronized (ClientSocketThread.class) {
int len = socket.getInputStream().read(buf, 0, buf.length);
if(len == -1)
break;
if(callback != null)
callback.onReceive(this, this, buf, len);
else if(parent != null)
((ServerSocketThread)parent).doReceive(this, buf, len);
//}
}
catch (SocketTimeoutException e) {
}
}
socket.close();
if(callback != null)
callback.onClose(this, socket != null ? 0 : -1);
else if(parent != null)
((ServerSocketThread)parent).doClose(this, 0);
System.out.println("client.close()-------------------");
}
catch (IOException e) {
e.printStackTrace();
}
}
}
//client端:
thread = new ClientSocketThread();
thread.connect(addr, port);
thread.setCallback(this);
thread.start();
//server端
thread = new ServerSocketThread();
thread.bind(port);
thread.setCallback(this);
thread.start();