【TX】在JAVA中使用Socket(即套接字)完成TCP程序的设计,使用此类可以方便的简历可靠的,双向的,持续的,点对点的通信连接。
在Socket的程序开发中,服务器使用ServerSocket等待客户端的连接,对于JAVA的网络程序来讲,每一个客户端都使用一个Socket对象表示。在服务器端每次运行都要使用accept()方法等待客户端的连接,此方法执行之后服务器端将进入阻塞状态,直到客户端连接之后程序才可以向下继续执行。此方法返回值类型为Socket,每一个Socket都表示一个客户端对象。在客户端,程序可以通过Socket类的getInputStream()方法取得服务器的输出信息,在服务器端可以通过getOutputStream()方法获取客户端的输出信息。
例1:服务端程序
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
public class ServerTest {
public static void main(String[] args) throws Exception {
ServerSocket server=new ServerSocket(8888);
System.out.println("服务器运行,等待客户端连接:");
Socket client=server.accept();
PrintStream out=new PrintStream(client.getOutputStream());
String str="我是服务端";
out.print(str);
out.close();
client.close();
server.close();
}
}
程序运行结果:注意目前处于阻塞状态
例2:客户端案例
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.Socket;
public class ClientTest {
public static void main(String[] args) throws Exception {
Socket client=new Socket("localhost",8888);
BufferedReader buf=new BufferedReader(new InputStreamReader(client.getInputStream()));
String readLine = buf.readLine();
System.out.println("服务器端传递的内容:"+readLine);
client.close();
buf.close();
}
}
程序运行结果:
现在观察例1的运行结果变化:
此时客户端从服务端将信息读取进来,读取完毕后,因为服务器端此时只能处理一次连接请求,所以也将关闭服务。这样显然是不可以的,所以对于服务端而言,需要加入多线程机制,每一个客户端连接时均启动一个新的线程。
例3:多线程处理
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;
public class ServerThread implements Runnable{
private Socket client=null;
public ServerThread(Socket client) {
super();
this.client = client;
}
@Override
public void run() {
PrintStream out=null;
BufferedReader buf=null;
try {
buf=new BufferedReader(new InputStreamReader(this.client.getInputStream()));
out=new PrintStream(client.getOutputStream());
boolean flag=true;
while(flag){
String readLine = buf.readLine();
if(readLine==null || "".equals(readLine)){
flag=false;
}else{
if("bye".equals(readLine)){
flag=false;
}else{
out.println("服务器返回给客户端信息:"+readLine);
}
}
}
out.close();
client.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
例4:服务端
import java.net.ServerSocket;
import java.net.Socket;
public class ServerTest {
public static void main(String[] args) throws Exception {
ServerSocket server=new ServerSocket(8888);
Socket client=null;
boolean flag=true;
while(flag){
System.out.println("服务器运行,等待客户端连接:");
client=server.accept();
new Thread(new ServerThread(client)).start();
}
server.close();
}
}
例5:客户端
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;
public class ClientTest {
public static void main(String[] args) throws Exception {
Socket client=new Socket("localhost",8888);
BufferedReader buf=new BufferedReader(new InputStreamReader(client.getInputStream()));
PrintStream out=new PrintStream(client.getOutputStream());
BufferedReader input=new BufferedReader(new InputStreamReader(System.in));
boolean flag=true;
while(flag){
System.out.println("输入请求信息:");
String readLine = input.readLine();
out.println(readLine);
if("bye".equals(readLine)){
flag=false;
}else{
String str=buf.readLine();
System.out.println(str);
}
}
client.close();
buf.close();
}
}
程序执行结果:
客户端:
这样,在服务器端,每一个连接到服务器的客户端Socket都会以一个线程的方式运行,这样无论有多少个客户端连接都可以同时完成操作