1、本地控制台的标准输入输出
EchoPlayer.java
字符流需要字节流转换
System.in提供控制台输入流
BufferedReader提供了字符流一行的读取
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
public class EchoPlayer {
public String echo(String msg){
return "echo:"+msg;
}
public void talk() throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String msg = null;
while((msg = br.readLine())!=null){
System.out.println(echo(msg));
if(msg.equals("bye")){
break;
}
}
}
public static void main(String[] args) throws IOException {
new EchoPlayer().talk();
}
}
2、简易客户端服务端通信
EchoServer.java
通过ServerSocket创建服务端监听
当accept()方法监听客户端连接返回Socket
根据Socket获取输入输出流
new PrintWriter(socketOut,true);
true表示覆盖前面的内容
PrintWriter内部封装了new BufferedWriter(new OutputStreamWriter(out))
输入流
InputStream socketIn = socket.getInputStream();
return new BufferedReader(new InputStreamReader(socketIn));
输出流
OutputStream socketOut = socket.getOutputStream();
return new PrintWriter(socketOut,true);
EchoClient.java
通过创建Socket建立服务端连接
public class EchoServer {
private int port = 8000;
private ServerSocket serverSocket;
public EchoServer() throws IOException {
serverSocket = new ServerSocket(port);
System.out.println("服务器启动");
}
public String echo(String msg){
return "echo:"+msg;
}
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 service(){
while(true){
Socket socket = null;
try {
socket = serverSocket.accept();
System.out.println("一个新的客户端连接:"+socket.getInetAddress()+":"+socket.getPort());
BufferedReader br = getReader(socket);
PrintWriter pw = getWriter(socket);
String msg = null;
while((msg=br.readLine())!=null){
System.out.println(msg);
pw.println(echo(msg));// 将接收到的消息再写回去
if(msg.equals("bye")){
break;
}
}
} catch (IOException e) {
e.printStackTrace();
} finally{
if(socket != null){
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
public static void main(String[] args) throws IOException {
new EchoServer().service();
}
}
public class EchoClient {
private String host = "localhost";
private int port = 8000;
private Socket socket;
public EchoClient() throws IOException {
socket = new Socket(host, port);
}
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(){
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) {
e.printStackTrace();
} finally {
if(socket != null){
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) throws IOException {
new EchoClient().talk();
}
}
3、判断端口是否被服务器程序监听
PortScanner.java
创建Socket,如果能够建立连接表示被监听
public class PortScanner {
public void scan(String host){
Socket socket = null;
for(int port=1;port<1024;port++){
try {
socket = new Socket(host, port);
System.out.println("There is aserver on port"+port);
} catch (IOException e) {
System.out.println("Can't connect to port"+port);
} finally {
if(socket != null){
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
public static void main(String[] args){
String host = "localhost";
if(args.length>0)host = args[0];
new PortScanner().scan(host);
}
}
4、Socket常见异常
ConnectTester.java
javac编译需要到包下,编译不用包名
java运行不用到包下,需要包名
C:\Users\Administrator\Desktop\Socket\socket2\src\main\java>java com.example.ConnectTester www.baidu.com 80
www.baidu.com/180.97.33.108:80 : 16ms
UnknownHostException 无法识别主机的名字或IP地址
ConnectException 没有服务器进程监听指定端口(未试成功)或服务器进程拒绝连接
server:
ServerSocket serverSocket = new ServerSocket(8000,2); //连接请求队列的长度为2
Thread.sleep(360000); //睡眠6分钟
client:
Socket s1 = new Socket("localhost",8000);
System.out.println("第一次连接成功");
Socket s2 = new Socket("localhost",8000);
System.out.println("第二次连接成功");
Socket s3 = new Socket("localhost",8000);
System.out.println("第三次连接成功");
SocketTimeoutException 连接超时
BindException 无法绑定指定的本地IP地址或端口
public class ConnectTester {
public void connect(String host, int port){
SocketAddress remoteAddr = new InetSocketAddress(host, port);
Socket socket = null;
String result = "";
try {
long begin = System.currentTimeMillis();
socket = new Socket();
socket.connect(remoteAddr, 1000);// 连接超时时间
long end = System.currentTimeMillis();
result = (end-begin)+"ms";
}catch (BindException e) {
result="Local address and port can't be binded";
}catch (UnknownHostException e) {
result="Unknown Host";
}catch (ConnectException e) {
result="Connection Refused";
}catch (SocketTimeoutException e) {
result="TimeOut";
}catch (IOException e) {
result="failure";
} finally {
try {
if(socket!=null)socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
System.out.println(remoteAddr+" : "+result);
}
public static void main(String[] args){
String host = "localhost";
int port = 25;
if(args.length>1){
host = args[0];
port = Integer.parseInt(args[1]);
}
new ConnectTester().connect(host, port);
}
}
5、模拟HTTP
HTTPClient.java
Socket建立连接,写与读数据
接收数据可用字节数组输出流暂存数据
接收的socket输入流写入字节数组输出流
InputStream socketIn = socket.getInputStream();
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
byte[] buff = new byte[1024];
int len;
while((len=socketIn.read(buff))!=-1){
buffer.write(buff, 0, len);
}
System.out.println(new String(buffer.toByteArray()));
半关闭Socket
shutdownInput()关闭输入流
shutdownOutput()关闭输出流
public class HTTPClient {
String host = "www.javathinker.org";
int port = 80;
Socket socket;
public void createSocket() throws IOException {
socket = new Socket(host, port);
}
public void communicate() throws IOException {
StringBuffer sb=new StringBuffer();
// sb.append("\"GET \"+\"/index.jsp\"+\" HTTP/1.1\\r\\n\"");
sb.append("Host: "+host+"\r\n");
sb.append("Accept: */*\r\n");
sb.append("Accept-Language: zh-cn\r\n");
sb.append("Accept-Encoding: gzip, deflate\r\n");
sb.append("User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)\r\n");
sb.append("Connection: Keep-Alive\r\n\r\n");
// 发出HTTP请求
OutputStream socketOut = socket.getOutputStream();
socketOut.write(sb.toString().getBytes());
/*// 关闭输出流*/
socket.shutdownOutput();
// 接收响应
InputStream socketIn = socket.getInputStream();
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
byte[] buff = new byte[1024];
int len;
while((len=socketIn.read(buff))!=-1){
buffer.write(buff, 0, len);
}
System.out.println(new String(buffer.toByteArray()));
socket.close();
}
public static void main(String[] args) throws IOException {
HTTPClient client = new HTTPClient();
client.createSocket();
client.communicate();
}
}