执行过程:
1,首先TCP服务程序创建ServerSocket类实例
执行accept方法,等待客户端发出请求
2,客户端创建Socket实例,发送连接请求。
3,服务器端接收到请求后,创建一个新的Socket建立与客户端的专线连接
4,通过这条专线即单独的线程上,与客户端对话。
5,服务器端开始等待新的客户端请求。重复2-5的步骤
编写TCP通信涉及类:服务器端:ServerSocket()不能直接使用。需要bind方法才可用。ServerSocket(int port)//指定端口号。如果0,系统自动分配。backlog默认10。一般用此方法ServerSocket(int port,int backlog)backlog 服务器很忙时,可以保持连接用户的数量。ServerSocket(int port,int backlog,InetAddress bindAddr)//bindAddr适用于多网卡,多IP时accept用于等待客户端的请求。 客户端:Socket()对象需要调用Connect();才可以。
其他函数类似ServerSocket();
Acpet返回服务器端的socket对象。用getInputStream和getOutputStream进行交互。
TCP通信以网络字节流的方式交换数据。
getInputStream用于返回输入流对象。
getOutputStream用户返回输出流对象
只要客户端和服务器建立了专线连接之后,一端向输出流写入了数据。另一端就可以在输入流中读取
TCP服务器模型编写要点:
1,需接收多个客户端连接时,要循环调用ServerSocket.accept方法
2,服务器程序和每个客户端连接的会话过程不能相互影响,需要在独立的线程中运行。
3,一个线程服务对象与一个服务器端Socket对象相关联,共同来完成于一个客户端的会话。
DEMO:
import java.net.*; //服务器端接收程序class ReverseServer { public static void main(String[] args) {
ServerSocket ss=null; try{ if(args.length<1) ss=new ServerSocket(8001); else ss=new ServerSocket(Integer.parseInt(args[0])); while(true){//接收多个客户端连接 Socket s=ss.accept();//等待客户端请求 new Thread(new Servicer(s)).start();//启动一个线程维护对话 } }catch(Exception e){ e.printStackTrace(); } }}
import java.net.*;import java.io.*;//处理程序class Servicer implements Runnable{ private Socket s=null; public Servicer(Socket s){ this.s=s; }
public void run(){ try{ InputStream ips=s.getInputStream();//获取客户端字节流 OutputStream ops=s.getOutputStream(); BufferedReader br=new BufferedReader( new InputStreamReader(ips) );//字节流转字符流
PrintWriter pw=new PrintWriter(ops,true);//创建输出字符流 while(true){ String strLine=br.readLine();//读取字符 if(strLine.equalsIgnoreCase("quit")) break; String strEcho=(new StringBuffer(strLine).reverse()).toString();//反向排列 pw.println(strLine+"-->"+strEcho);//换行符根据操作系统调整。 }
br.close(); pw.close(); s.close(); }catch(Exception e){ e.printStackTrace(); } }}
//客户端程序
import java.io.*;import java.net.*;class TcpClient { public static void main(String[] args) { try{ if(args.length<2){ System.out.println("Use:IPAddress,port"); return; } Socket s=new Socket(args[0],Integer.parseInt(args[1])); InputStream ips=s.getInputStream(); OutputStream ops=s.getOutputStream(); BufferedReader brNet=new BufferedReader( new InputStreamReader(ips)); PrintWriter pw=new PrintWriter(ops,true); BufferedReader brKeyBoard=new BufferedReader( new InputStreamReader(System.in));
while(true){ String strWord=brKeyBoard.readLine(); pw.println(strWord); if(strWord.equalsIgnoreCase("quit"))break; System.out.println(brNet.readLine());
}
pw.close(); brNet.close(); brKeyBoard.close(); s.close(); }catch(Exception e){ e.printStackTrace(); } }}
检测端口冲突问题:
netstat -na