分单线程和多线程两种情况来讲
1.单线程中的基于TCP的Socket通信。首先来建服务端的Socket通信。
第一步:创建一个ServerSocket对象并指定端口。
ServerSocket serversocket=new ServerSocket(8888);
第二步:通过serversocket实例的accept方法创建一个Socket对象
Socket socket= serversocket.accept();
第三步:通过socket实例的getInputStream获得一个InputStream对象。
InputStream is= socket.getInputStream();
第四步:将字节输入流转化为字符输入流,并添加缓存
InputStreamReader isr=new InputStreamReader(is);
BufferedReader br=new BufferedReader(isr);
第五步:读出接收到的信息,通过br实例的readline方法,这样我们就接受到了客户端发送的信息,记得要关闭socket实例的输入
String info=null;
while((info=br.readLine())!=null)
{
System.out.println("服务端:"+info);
}
socket.shutdownInput();
第六步;给客户端发出响应,首先通过socket实例的getOutputStream方法获得一个输出流对象OutputStream
OutputStream os= socket.getOutputStream();
第七步:将字节输出流对象转化为打印流对象PrintWriter,并通过其write填写要输出的内容,并清空缓冲区,记得要关闭socket实例的输出
PrintWriter pw=new PrintWriter(os);
pw.write("欢迎您");
pw.flush();
第八步:关闭所有要关闭的实例
os.close();
pw.close();
is.close();
isr.close();
br.close();
socket.close();
serversocket.close();
然后来建立客户端的socket通信,新建一个客户端类
第一步:创建一个Socket对象,参数为主机名和端口号,主机名可以通过inetaddress类获得,这里取本机
Socket socket=new Socket("localhost",8888);
第二步:通过Socket实例的getOutputStream方法创建一个输入流对象,这里的实现与服务端很像,不再赘述。
OutputStream os= socket.getOutputStream();
PrintWriter pw=new PrintWriter(os);
pw.write("我是客户端,你好");
pw.flush();
socket.shutdownOutput();
第三步:我们也要去接收服务端发来的信息,方法同服务端
InputStream is=socket.getInputStream();
InputStreamReader isr=new InputStreamReader(is);
BufferedReader br=new BufferedReader(isr);
String info=null;
while((info=br.readLine())!=null)
{
System.out.println(info);
}
socket.shutdownInput();
br.close();
isr.close();
is.close();
os.close();
接下来我们就可以测试,记得先启动服务端,再启动客户端
多线程的原理其实是一样的,知识要把主要方法放在多线程的类中
第一步:创建一个服务端线程类,该类继承自Thread类,先创建一个socket对象,并定义类的构造方法
Socket socket=null;
public ServerThread(Socket socket)
{
this.socket=socket;
}
第二步:在run方法中写入主要代码。主要代码即刚开始实现的单线程的主要代码。这个线程类就完成了。
public void run()
{
InputStream is;
try {
is = socket.getInputStream();
InputStreamReader isr=new InputStreamReader(is);
BufferedReader br=new BufferedReader(isr);
String info=null;
while((info=br.readLine())!=null)
{
System.out.println("服务端:"+info);
}
socket.shutdownInput();
OutputStream os= socket.getOutputStream();
PrintWriter pw=new PrintWriter(os);
pw.write("欢迎您");
pw.flush();
socket.shutdownOutput();
os.close();
pw.close();
is.close();
isr.close();
br.close();
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
第三步:在服务端的那个类中也要进行修改,这里可以定义一个整型count,记录客户端的数目。由于我们要不断侦听客户端,所以要写一个死循环,并且不必关闭Serversocket。这是修改后main方法
public static void main(String[] args) {
ServerSocket serversocket;
try {
serversocket = new ServerSocket(8888);
int count=0;
Socket socket=null;
while(true)
{
socket= serversocket.accept();
ServerThread serverthread= new ServerThread(socket);
serverthread.start();
count++;
System.out.println(count);
}
//serversocket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}