1、Socket:英文意思插座。两个Java应用程序可以通过一个双向的网络通信连接实现数据交换,这个双向链路的一端称为一个Socket。
2、Socket通常用来实现client-server(客户端与服务器)连接。
3、java.net包中定义的两个类Socket和ServerSocket,分别用来实现双向连接的client客户端和server服务器端。
4、建立连接时所需的寻址信息为远程计算机的IP地址和端口号。
5、端口号:区分一台机器上不同的应用程序,在计算机内部两个字节(65536个端口号),一个应用可能占多个端口号。每个端口号只能被一个应用程序占用,自己用端口的时候,用1024以上的,因为1024以下的可能会被操作系统征用。http协议的默认端口是80.
6、端口号又分为TCP端口和UDP端口,两类端口各有65536个端口号。

7、写网络编程代码时需要注意:
(1)首先启Server,再启Client。写的时候要Server和Client一起写。
(2)ServerSocket是阻塞性质的,要等到client连接才会停止等待。
(3)网络通讯过程:
a. Server端new一个ServerSocket 对象,往往在new ServerSocket的时候要给它一个端口号。启动监听,然后等待客户端的连接。
import java.net.*;
public class TcpServer{
public static void main(String args[]) throws Exception{
ServerSocket ss = new ServerSocket(6666);
}
}
注意:自定义的Java类的名字不能和Java虚拟机提供的类名相同,否则不能编译通过。用dos命令编译java文件时,java文件名称必须和文件中的class名称相同。
b. Client端new一个Socket对象,在new的时候给一个服务器端的IP地址和服务器端的端口号。client的端口是系统随机选一个就可以了,一旦和服务器端建立起连接,这个端口就归这一对服务器和客户所用了(Client 申请连接) 。Client 申请连接后,server端不一定接收,接收用accept方法。
import java.net.*;
public class TcpClient{
public static void main(String args[]) throws Exception{
Socket s = new Socket("127.0.0.1",6666);
}
}
c. Server端调用accept方法接收客户端的连接申请,返回一个Socket对象,专门用于和发请求的那一个客户端进行对话。如果有其他的客户端再发来请求,再建立连接,则Server端再次调用accept()方法,产生一个新的Socket对象,用于和新的客户端通讯。
import java.net.*;
public class TcpServer{
public static void main(String args[]) throws Exception{
ServerSocket ss = new ServerSocket(6666);
Socket s = ss.accept();
}
}
目前为止的写法Server只能连一个Client,连接一个新Client时,必须重新启Server。为了实现多个客户端连接同一个Server,通常将Server的accept()方法和其他操作放在while(true)里。
import java.net.*;
public class TcpServer{
public static void main(String args[]) throws Exception{
ServerSocket ss = new ServerSocket(6666);
while(true){
Socket s = ss.accept();
System.out.println("a new connection");
}
}
}
这样就可以启一个Server供多个Client连接。
d. Server端和Client通过管道(流 )来说话
client端说话用输出流:
import java.net.*;
import java.io.*;
public class TcpClient{
public static void main(String args[]) throws Exception{
Socket s = new Socket("127.0.0.1",6666);
OutputStream os = s.getOutputStream();
DataOutputStream dos = new DataOutputStream(os);
Thread.sleep(30000);//睡眠30秒,如果这30秒之间有另一个客户端连接这个server,则连不上,会一直等待上一个客户端说话结束后或者30秒后才能连上。
dos.writeUTF("hello server");//以UTF-8的编码格式写字符串
dos.flush();
dos.close();
s.close();
}
}
server端用输入流接收:
import java.net.*;
import java.io.*;
public class TcpServer{
public static void main(String args[]) throws Exception{
ServerSocket ss = new ServerSocket(6666);
while(true){
Socket s = ss.accept();
System.out.println("a new connection");
InputStream is = s.getInputStream();
DataInputStream dis = new DataInputStream(is);
System.out.println(dis.readUTF());
dis.close();
s.close();
}
}
}
注:readUTF也是阻塞式的,它会一直等到对方写东西过来才会继续执行,如果客户端一直不写东西过来,server端会一直等待,直到客户端写了东西过来,期间不能接受其他客户端。
目前为止学到的是同步式的,阻塞式的效率低;java提供异步式网络编程,效率会更高。