1、将数据发送给那个进程靠端口决定。
2、端口范围0-65535.
21为FTP,25为SMTP,80为HTTP,125为RPC(远程过程调用)
3、TCP、UDP取值独立,允许存在取值相同的TCP、UDP端口。
4、java中3种套接字:java.net.Socket,java.net.ServerSocket(TCP)
java.DatagramSocket(UDP)c/s模式。
客服端与服务端程序:
package ClientEcho;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
public class ClientEcho {
private String host="127.0.0.1";
private int port=80;
private Socket socket;
public ClientEcho()throws IOException{
socket=new Socket(host,port);
}
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
System.out.println("客服端启动");
new ClientEcho().talk();
}
private PrintWriter getWriter(Socket socket)throws IOException{
OutputStream socketOut=socket.getOutputStream();
return new PrintWriter(socketOut,true);
}
private BufferedReader getReader(Socket socket)throws IOException{
InputStream socketIn=socket.getInputStream();
return new BufferedReader(new InputStreamReader(socketIn));
}
public void talk()throws IOException{
try {
BufferedReader br=getReader(socket);
PrintWriter pw=getWriter(socket);
BufferedReader localReader=new BufferedReader(new InputStreamReader(System.in));
String msg=null;
while((msg=localReader.readLine())!=null){
pw.println(msg);
System.out.println(br.readLine());
if(msg.equals("bye"));
break;
}
} catch (IOException e) {
// TODO: handle exception
e.printStackTrace();
}finally{
try {
socket.close();
} catch (IOException e2) {
// TODO: handle exception
e2.printStackTrace();
}
}
}
/**
* @param args
* @throws IOException
*/
}
package ServeEcho;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import javax.swing.text.AbstractDocument.LeafElement;
public class ServeEcho {
private int port=80;
private ServerSocket serverSocket;
public ServeEcho() throws IOException{
serverSocket=new ServerSocket(port);
System.out.println("服务器启动");
}
public String echo(String msg){
return "echo:"+msg;
}
private PrintWriter getPrintWriter(Socket socket)throws IOException {
OutputStream socketOut=socket.getOutputStream();
return new PrintWriter(socketOut, true);
}
private BufferedReader getReader(Socket socket) throws IOException {
InputStream socketIn=socket.getInputStream();
return new BufferedReader(new InputStreamReader(socketIn));
}
public void service() {
while(true){
Socket socket=null;
try {
socket=serverSocket.accept();
System.out.println("New connection accepted"+socket.getInetAddress()+":"+socket.getPort());
BufferedReader br=getReader(socket);
PrintWriter pw=getPrintWriter(socket);
String msg=null;
while((msg=br.readLine())!=null){
System.out.println(msg);
pw.println(echo(msg));
if(msg.equals("bye"))
break;
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}finally{
try {
if(socket!=null)
socket.close();
} catch (Exception e2) {
// TODO: handle exception
e2.printStackTrace();
}
}
}
}
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
new ServeEcho().service();
}
}
5、InetAddress类表示服务器的IP地址
6、关闭Socket:
isClosed()已经连接,还没关闭,返回true。
isConnected()曾经连接
isBound()已经绑定。
半关闭:shutdownInput
shutdownOutput
7、设置Socket:
TCP_NODELAY 默认false,采用Negale算法,缓冲之后一次发送,有利于发送大量数据,且要求对方有回应。
小批量数据则需要调用setTCPDelay(true)方法,关闭缓冲,确保及时发送。