首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > JAVA > Java相关 >

java多线程 Socket解决思路

2013-04-12 
java多线程Socket我的主要想法是做一个服务器 可以让两个用户之间进行消息,文件传输。为此我在客户端为每个

java多线程 Socket
我的主要想法是做一个服务器 可以让两个用户之间进行消息,文件传输。为此我在客户端为每个用户开辟了两个线程 一个用于文件传输一个用于消息传输,每个线程都有一个与之对应的Socket连接 同样在服务器端也为每个与它连接的客户端开了两个线程(文件传输线程,消息线程) 用来在两个客户端之间进行消息的转发。同时我将客户端与服务器端的线程都做成了死循环 以此来不断得读取传送过来的消息和文件信息。可是当我创建了一个用户时cpu的占用率就40%左右了再开一个就100% 有点崩溃了在这样下去的话,后来的什么也做不了了?java多线程   Socket解决思路求大神们帮帮看看啊到底是哪里出了问题啊,是因为我没有将线程休眠吗?那又应该在哪里休眠呢?新手请求大家的指教java多线程   Socket解决思路
同时还有一个问题在下面代码中已经标注也请大家看看啊,小女子不胜感激。
服务器端代码
public class Server1 {
public static void main(String[] args) {
try {
ServerSocket ss = new ServerSocket(9999);
System.out.println("服务器9999号端口在监听。。");
int a = 1;//这里的a没有任何的意义,只是为了简化代码,使第一次是消息线程连接 与之连接  第二次是文件传输线程

while (true) {
Socket s = ss.accept();
if (a == 1) {
MessageServerThread mst = new MessageServerThread(s);
mst.start();
System.out.println("服务器端传输消息线程开启" + mst.getName());
a = 2;
} else if (a == 2) {
TransportFileServerThread tfst = new TransportFileServerThread(
s);
tfst.start();
System.out.println("服务器端传输文件线程开启" + tfst.getName());
a = 1;
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
客户端代码:

public class LoginFrame {
public static void main(String[] args) {
// 启动两个线程
Socket s;
try {
// 用户1
s = new Socket("127.0.0.1", 9999);
MessageClientThread mct = new MessageClientThread(s);
mct.start();
System.out.println("客户端1消息线程开启" + mct.getName());
s = new Socket("127.0.0.1", 9999);
TransportFileClientThread tfct = new TransportFileClientThread(s);
tfct.start();
System.out.println("客户端1文件传输线程开启" + tfct.getName());
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
客户端文件传输线程代码:
public class TransportFileClientThread extends Thread {
Socket s;

public TransportFileClientThread(Socket s) {
this.s = s;
}
    public void run() {
while (true) {
try {
DataInputStream dis = new DataInputStream(
new BufferedInputStream(s.getInputStream()));
//之后将文件保存在本地
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
客户端消息线程代码:

public class MessageClientThread extends Thread {
Socket s;

public MessageClientThread(Socket s) {
this.s = s;
}

public void run() {
while (true) {
try {
ObjectInputStream ois = new ObjectInputStream(
s.getInputStream());
//之后处理得到的消息
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}


}
服务器端文件传输代码:

import java.io.*;
import java.net.*;

public class TransportFileServerThread extends Thread {

Socket s;

public TransportFileServerThread(Socket s) {
this.s = s;
}

public void run() {
while (true) {
try {
DataInputStream dis = new DataInputStream(
new BufferedInputStream(s.getInputStream()));
// 之后完成文件的转发
                                DataOutputStream dos = new DataOutputStream(
new BufferedOutputStream(new FileOutputStream(
按照 接收端的 Socket连接进行转发)));
byte[] buf = new byte[1024];
int count;
while ((count = dis.read(buf)) != -1) {
dos.write(buf, 0, 1);
dos.flush();
}
System.out.println("文件传输完毕");这就话不知道为什么老是没有执行,那是不是说明上面的while循环没有走完啊可是并没有看出代码哪里有问题啊?而且文件也的确是转发成功了 转发后的文件也创建成功了里面也有内容 可是就是不输出这句话是哪里出了问题呢java多线程   Socket解决思路求大家的指教啊
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}

服务器端消息线程代码:
public class MessageServerThread extends Thread {

Socket s;

public MessageServerThread(Socket s) {http://news.csdn.net//images/top_arrow.png
this.s = s;
}

public void run() {
while (true) {
try {
ObjectInputStream ois = new ObjectInputStream(
s.getInputStream());
System.out.println("之后将信息转发给另一个人。。");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
[解决办法]
亲,socket的while ((count = dis.read(buf)) != -1) 是不会读到-1的,会一直阻塞等待另一端发来数据的。

一般传文件的做法是 定义一个格式  比如先  文件名   文件长度  文件内容  按照这张格式发送数据的,先读到文件名和文件长度然后根据文件长度再来读取流数据。
[解决办法]
给你写了个小demo

public class Server {

public static void main(String[] args) throws Exception {
new Server().start();
}

public void start() throws Exception {
ServerSocket server = new ServerSocket(7789);

Socket client = server.accept();

System.out.println(client.getInetAddress() + "已连接");

DataInputStream dis = new DataInputStream(client.getInputStream());
DataOutputStream dos = new DataOutputStream(client.getOutputStream());

boolean flag = false;

try {
flag = dis.readBoolean();// 读取客户端发送文件的请求
} catch (Exception e) {// 不符合标准断开连接
dos.writeChars("Illegal request");// 返回非法请求信息
dos.flush();

client.close();// 关闭连接
}

if (flag) {
dos.writeBoolean(true);// 告诉客户端可以开始传输文件了



String fileName = dis.readUTF();// 读取文件名
long fileSize = dis.readLong();// 读取文件长度

byte[] buff = new byte[4096];
int len = 0;
int count = 0;

FileOutputStream fos = new FileOutputStream("c:/data/" + fileName);

while (count < fileSize) {
len = dis.read(buff);

fos.write(buff, 0, len);

count += len;
}

fos.flush();
fos.close();

System.out.println(fileName + "传输完毕!");

dos.writeBoolean(true);
dos.flush();

client.close();
}
}
}




public class Client {

public static void main(String[] args) throws Exception {
new Client().start();
}

public void start() throws Exception {
Socket server = new Socket("localhost", 7789);

DataInputStream dis = new DataInputStream(server.getInputStream());
DataOutputStream dos = new DataOutputStream(server.getOutputStream());

dos.writeBoolean(true);// 发送传输文件请求
dos.flush();

boolean flag = false;

try {
flag = dis.readBoolean();// 读取服务端返回信息
} catch (Exception e) {// 不符合标准断开连接
dos.writeChars("Illegal message");// 返回非法请求信息
dos.flush();

server.close();// 关闭连接
}

if (flag) {

File file = new File("c:/jdk-6u43-windows-x64.exe");
FileInputStream fis = new FileInputStream(file);

dos.writeUTF(file.getName());// 发送文件名
dos.writeLong(file.length());// 发送文件大小

// 发送文件
byte[] buff = new byte[4096];
int len = -1;

while ((len = fis.read(buff)) != -1) {
dos.write(buff, 0, len);
}
dos.flush();

fis.close();

if (dis.readBoolean()) {// 等待服务器端完成
server.close();
}
}
}
}

[解决办法]
引用:
引用:给你写了个小demo

Java code?1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859public class Server {     public ……


选择文件并确定要传文件的时候创建线程比较好
[解决办法]
引用:
引用:其实你研究下DataInputStream和DataOutputStream 的源码你就会发现,他们都是按照一定的约定来发送数据的。
嗯嗯看了些不过不太明白 再研究研究吧 想问一下哈 你的代码 是怎么处理的呢为什么我只会复制粘贴 导致看起来代码乱乱的 是用什么工具做到的吗?


额,csdn的编辑框表情左边的就是插代码的,会帮你自动着色和排版的
[解决办法]
嗯 。。。   你后面可能还会有用socket传输对象的问题。因为交流的数据复杂的话最好用对象来封装。
这个还好办的一点。 要是想实现跨语言对象传输就更难搞了 。 例如服务器用java,客户端用c#。 我最近在搞这个。  我发了个贴,顺便在这求助一下

热点排行