TCP:传输控制协议,采用三方握手的方式,保证准确的连接操作,传输效率不如UDP高
UDP:数据包协议,发送数据报。例如手机短息、QQ消息
什么是Socket
网络上的两个程序通过一个双向的通讯连接实现数据的交换,这个双向链路的一端称为一个Socket。Socket通常用来实现客户方和服务方的连接。Socket是TCP/IP协议的一个十分流行的编程界面,一个Socket由一个IP地址和一个端口号唯一确定。
Socket通讯的过程
1、服务器端监听某个端口是否有连接请求
ServerSocketserver = new ServerSocket(9999);//传入监听的端口号
2、客户端端向服务器端端发出连接请求
Socket client =new Socket(192.168.1.1,9999);
3、服务器端向客户端端发回Accept(接受)消息
Socket client =server.accept();
4、Server端和Client端都可以通过Send,Write等方法与对方通信。
创建客户端:
(1) 创建Socket;
(2) 打开连接到Socket的输入/出流;
(3) 按照一定的协议对Socket进行读/写操作;
(4) 关闭Socket.
简单的Client/Server程序
1. 客户端程序
importjava.io.*;
importjava.net.*;
publicclass TalkClient {
publicstatic void main(String args[]) {
try{
Socketsocket=new Socket("127.0.0.1",4700);
BufferedReadersin=new BufferedReader(new InputStreamReader(System.in));
PrintWriteros=new PrintWriter(socket.getOutputStream());
//由Socket对象得到输出流,并构造PrintWriter对象
BufferedReaderis=new BufferedReader(new InputStreamReader(socket.getInputStream()));
//由Socket对象得到输入流,并构造相应的BufferedReader对象
Stringreadline;
readline=sin.readLine();//从系统标准输入读入一字符串
while(!readline.equals("bye")){
//若从标准输入读入的字符串为"bye"则停止循环
os.println(readline);
//将从系统标准输入读入的字符串输出到Server
os.flush();
//刷新输出流,使Server马上收到该字符串
System.out.println("Client:"+readline);
//在系统标准输出上打印读入的字符串
System.out.println("Server:"+is.readLine());
//从Server读入一字符串,并打印到标准输出上
readline=sin.readLine();//从系统标准输入读入一字符串
} //继续循环
os.close();//关闭Socket输出流
is.close();//关闭Socket输入流
socket.close();//关闭Socket
}catch(Exceptione) {
System.out.println("Error"+e);//出错,则打印出错信息
}
}
}
2. 服务器端程序
importjava.io.*;
importjava.net.*;
importjava.applet.Applet;
publicclass TalkServer{
publicstatic void main(String args[]) {
try{
ServerSocketserver=null;
try{
server=newServerSocket(4700);
//创建一个ServerSocket在端口4700监听客户请求
}catch(Exceptione) {
System.out.println("cannot listen to:"+e);
//出错,打印出错信息
}
Socketsocket=null;
try{
socket=server.accept();
//使用accept()阻塞等待客户请求,有客户
//请求到来则产生一个Socket对象,并继续执行
}catch(Exceptione) {
System.out.println("Error."+e);
//出错,打印出错信息
}
Stringline;
BufferedReaderis=new BufferedReader(new InputStreamReader(socket.getInputStream()));
//由Socket对象得到输入流,并构造相应的BufferedReader对象
PrintWriteros=newPrintWriter(socket.getOutputStream());
//由Socket对象得到输出流,并构造PrintWriter对象
BufferedReadersin=new BufferedReader(new InputStreamReader(System.in));
//由系统标准输入设备构造BufferedReader对象
System.out.println("Client:"+is.readLine());
//在标准输出上打印从客户端读入的字符串
line=sin.readLine();
//从标准输入读入一字符串
while(!line.equals("bye")){
//如果该字符串为"bye",则停止循环
os.println(line);
//向客户端输出该字符串
os.flush();
//刷新输出流,使Client马上收到该字符串
System.out.println("Server:"+line);
//在系统标准输出上打印读入的字符串
System.out.println("Client:"+is.readLine());
//从Client读入一字符串,并打印到标准输出上
line=sin.readLine();
//从系统标准输入读入一字符串
} //继续循环
os.close();//关闭Socket输出流
is.close();//关闭Socket输入流
socket.close();//关闭Socket
server.close();//关闭ServerSocket
}catch(Exceptione){
System.out.println("Error:"+e);
//出错,打印出错信息
}
}
}
支持多客户的client/server程序
前面的Client/Server程序只能实现Server和一个客户的对话。在实际应用 中,往往是在服务器上运行一个永久的程序,它可以接收来自其他多个客户端的请求,提供相应的服务。利用多线程实现多客户机制。服务器总是在指定的端口上监听是否有客户请求,一旦监听到客户请求,服务器就会启动一个专门的服务线程来响 应该客户的请求,而服务器本身在启动完线程之后马上又进入监听状态,等待下一个客户的连接。
ServerSocketserverSocket=null;
booleanlistening=true;
try{
serverSocket=newServerSocket(4700);
}catch(IOExceptione) { }
while(listening){//永远循环监听
newServerThread(serverSocket.accept(),clientnum).start();
//监听到客户请求,根据得到的Socket对象和
客户计数创建服务线程,并启动之
clientnum++;//增加客户计数
}
serverSocket.close();//关闭ServerSocket
设计ServerThread类
publicclass ServerThread extends Thread{
Socketsocket=null; //保存与本线程相关的Socket对象
intclientnum; //保存本进程的客户计数
publicServerThread(Socket socket,int num) { //构造函数
this.socket=socket;//初始化socket变量
clientnum=num+1;//初始化clientnum变量
}
publicvoid run() { //线程主体
try{//在这里实现数据的接受和发送}