开发客户端代码
我们可以按以下的步骤,编写的基于多线程的客户端代码。
第一步,在 “TCPSocket”项目里,新建一个名为ThreadClient.java的代码文件。同样是编写package和import部分的代码,用来打包和引入包文件,如下所示:
package tcp;
import java.net.*;
import java.io.*;
第二步,编写线程执行主体的ClientThreadCode类,同样,这个类通过继承Thread来实现线程的功能。
class ClientThreadCode extends Thread
{
//客户端的socket
private Socket socket;
//线程统计数,用来给线程编号
private static int cnt = 0;
private int clientId = cnt++;
private BufferedReader in;
private PrintWriter out;
//构造函数
public ClientThreadCode(InetAddress addr)
{
try
{
socket = new Socket(addr, 3333);
}
catch(IOException e)
{
e.printStackTrace();
}
//实例化IO对象
try
{
in = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
out = new PrintWriter(
new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
//开启线程
start();
}
catch(IOException e)
{
//出现异常,关闭socket
try
{
socket.close();
}
catch(IOException e2)
{
e2.printStackTrace();
}
}
}
//线程主体方法
public void run()
{
try
{
out.println("Hello Server,My id is " + clientId );
String str = in.readLine();
System.out.println(str);
out.println("byebye");
}
catch(IOException e)
{
e.printStackTrace();
}
finally
{
try
{
socket.close();
}
catch(IOException e)
{
e.printStackTrace();
}
}
}
}
这个类的主要业务逻辑是:
1. 在构造函数里, 通过参数类型为InetAddress类型参数和3333,初始化了本类里的Socket对象,随后实例化了两类IO对象,并通过start方法,启动定义在run方法内的本线程的业务逻辑。
2. 在定义线程主体动作的run方法里,通过IO句柄,向Socket信道上传输本客户端的ID号,发送完毕后,传输”byebye”字符串,向服务器端表示本线程的通讯结束。
3. 同样地,catch从句将处理在try语句里遇到的IO错误等异常,而在finally从句里,将在通讯结束后关闭客户端的Socket句柄。
第三步,编写客户端的主体代码,在这段代码里,将通过for循环,根据指定的待创建的线程数量,通过ClientThreadCode的构造函数,创建若干个客户端线程,同步地和服务器端通讯。
public class ThreadClient
{
public static void main(String[] args)
throws IOException, InterruptedException
{
int threadNo = 0;
InetAddress addr =
InetAddress.getByName("localhost");
for(threadNo = 0;threadNo<3;threadNo++)
{
new ClientThreadCode(addr);
}
}
}
这段代码执行以后,在客户端将会有3个通讯线程,每个线程首先将先向服务器端发送"Hello Server,My id is "的字符串,然后发送”byebye”,终止该线程的通讯。