我有多个套接字连接到不同的系统,不同的IP地址和不同的端口号。我的问题是我必须在任何系统中运行一个程序来一次通信所有套接字,我如何从套接字并行获取消息?
虽然我使用的是单插槽,但它可以正常工作,我会从超级终端连续收到消息。多个连接,然后我只得到第一个响应..所以请尽快提供解决方案
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.HashMap;
import com.ibatis.sqlmap.client.SqlMapClient;
public class Client1 extends Thread {
static Socket socket;
static Socket socket1;
static String DATE_FORMAT_NOW = "yyyy-MM-dd HH:mm:ss";
static SqlMapClient sqlMap=GetDBConnection.sqlMap;
static BufferedReader br = null;
static DataOutputStream dos=null;
static BufferedReader br1 = null;
static DataOutputStream dos1=null;
public static void main(String args[]){
try{
String host="192.168.1.151";
int port=5002;
String host1="192.168.1.150";
int port1=5001;
socket = new Socket(host, port);
socket1=new Socket(host1, port1);
dos = new DataOutputStream(socket.getOutputStream());
br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
dos1 = new DataOutputStream(socket1.getOutputStream());
br1 = new BufferedReader(new InputStreamReader(socket1.getInputStream()));
Thread t = new Thread(new Runnable() {
public void run() {
while(socket.isConnected()) {
try{
HashMap map = new HashMap();
String str = br.readLine();
Calendar cal = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT_NOW);
String time = sdf.format(cal.getTime());
map.put("data", str);
map.put("port", socket.getPort());
map.put("date_time", time);
sqlMap.insert("insert", map);
}
catch(Exception e){
e.printStackTrace();
}
}
}
});
Thread t1 = new Thread(new Runnable() {
public void run() {
while(socket1.isConnected()) {
try{
HashMap map = new HashMap();
String str = br1.readLine();
Calendar cal = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT_NOW);
String time = sdf.format(cal.getTime());
map.put("data", str);
map.put("port", socket1.getPort());
map.put("date_time", time);
sqlMap.insert("insert", map);
}
catch(Exception e){
e.printStackTrace();
}
}
}
});
t.start();
t1.start();
}
catch(Exception e){
e.printStackTrace();
}
}
}
我为两个套接字运行两个线程,它的工作正常,但如果我有100个套接字,那么我该怎么做呢?我不能创建100个线程...所以提供最好的解决方案..
public class Client implements Runnable{
public static final String DATE_FORMAT_NOW = "yyyy-MM-dd HH:mm:ss";
static BufferedReader br = null;
static DataOutputStream dos=null;
static Socket socket = null;
SqlMapClient sqlMap=GetDBConnection.sqlMap;
Client(String host, int port)
{
try {
socket = new Socket(host, port);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public void run()
{
try {
HashMap map = new HashMap(5);
String str;
int prt=socket.getPort();
dos = new DataOutputStream(socket.getOutputStream());
br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
while((str=br.readLine())!=null)
{
Calendar cal = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT_NOW);
String time = sdf.format(cal.getTime());
map.put("data", str);
map.put("port",prt );
map.put("date_time", time);
sqlMap.insert("insert", map);
}
}
catch(Exception e)
{
e.printStackTrace();
}
finally
{
try {
socket.close();
dos.close();
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void main(String args[])
{
ResultSet rs=null;
Connection con = null;
try {
Class.forName("org.postgresql.Driver");
con = DriverManager.getConnection("jdbc:postgresql://localhost:5432/Socket","username","passwd");
Statement st=con.createStatement();
String vsql="select port, ip_addr from port_instrument";
rs=st.executeQuery(vsql);
while (rs.next()) {
String id = rs.getString(1);
String ipaddr = rs.getString(2);
new Thread(new Client(ipaddr, Integer.parseInt(id))).start();
}
}
catch(Exception e)
{
e.printStackTrace();
}
finally{
try {
con.close();
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
通过使用此代码,我们只能与单个套接字进行通信。在我的数据库中,我有5个套接字,但最后我只从最后一个套接字(5)获得通信。
答案 0 :(得分:2)
您可能希望编写一个实现Runnable的通信类,并执行所有套接字通信。然后,您可以为每个套接字创建此类的实例,并在某种线程池中运行类。
编辑:这是一个开始
public class SocketHandler implements Runnable
{
private Socket socket;
public SocketHandler(String host, int port)
{
socket = new Socket(host, port);
}
public void run()
{
//Do the comms to the remote server
}
}
答案 1 :(得分:0)
Jboss Netty 是不错的选择。
答案 2 :(得分:0)
您需要从不同线程中的每个套接字读取,否则您的应用程序将阻止侦听其中一个套接字,即使有其他数据要读取。因此,如果您有x套接字,则必须创建从其中读取的x个线程。