点我跳过黑哥的卑鄙广告行为,进入正文。html
Java多线程系列更新中~java
正式篇:编程
番外篇(神TM番外篇):服务器
Socket是客户端和服务器端交流的端点。经过它能够实现客户端和服务器端的通讯。顺着这篇文章操做下来,你应该会对Socket编程有比较系统的了解。注意,跟着敲代码,有什么不懂而我又没提到的地方,随时百度,不要积累偏差。网络
Socket是有链接的,因此双方创建通讯,须要知道彼此的网络位置(IP和端口)。多线程
建立Socket对象:socket
Socket socket = new Socket("127.0.0.1",8852);
为何须要端口号?例如你想要去找你的暗恋对象告白,你知道她的学校地址(IP地址),可是一个学校不会只有你暗恋对象一我的(一个主机不会只进行一个任务),你须要知道她的宿舍号(端口号),这样才能方便告白。ide
使用本机既作客户端,又作服务器是个什么状况?就是你和你暗恋对象在同一个学校,这没什么区别,你仍然须要她的宿舍号(端口号)才能找到她告白(客户端和服务前通讯)。函数
public class MyClient { public static void main(String[] args) throws Exception{ Socket socket = new Socket("127.0.0.1",8852); DataOutputStream dataOutputStream = new DataOutputStream(socket.getOutputStream()); dataOutputStream.writeUTF("Hello socket"); socket.close(); } }
注意别忘了抛出异常,这里只是个演示做用,直接throws Exception了。这里你直接运行确定是不能创建链接的,由于服务器端还没写。spa
这里,假如你知道服务器监听的是8852端口,你建立了一个socket来和它进行通讯。socket.getOutputStream()获得这个socket的输出流,当你调用writeUTF()方法时,便会向其中写一个字符串。
典型三段式要牢记:打开、通讯、关闭。
注意了注意了,要开始造女票了。
import java.io.DataInputStream; import java.net.ServerSocket; import java.net.Socket; public class MyServer { public static void main(String[] args) throws Exception{ ServerSocket serverSocket = new ServerSocket(8852); System.out.println("Server 等待接收数据~"); Socket socket = serverSocket.accept(); DataInputStream dataInputStream = new DataInputStream(socket.getInputStream()); String string = dataInputStream.readUTF(); System.out.println(string); System.out.println("Server 接收数据完毕,拜拜了您~"); socket.close(); serverSocket.close(); } }
这里服务器端用到了ServerSocket,负责接收客户端的链接请求。你的暗恋对象可能有好多人要向她告白,一个Socket天然没法处理。经过ServerSocket的accept方法从链接请求队列中取出一个进行链接。那这个ServerSocket就是你暗恋对象的室友,帮助她管理诸多“告白”。
这里只是把服务器端接收到的数据打印了一下便关闭了。至此,一个简单的服务器-客户端通讯便创建了。可是这个服务器只能处理一个链接便关闭了,咱们能够改进一下。
往下看以前请确保你大体理解了上述过程,最好本身敲一下代码
到这里你可能会想,只处理一个就关闭了,那我加个while循环,让它一直运行怎么样?
听着还能够,那咱们来试验一下(下面只是分析一下,不用跟着敲)。
将服务器端代码更改成:
while(true) { Socket socket = serverSocket.accept(); DataInputStream dataInputStream = new DataInputStream(socket.getInputStream()); String string = dataInputStream.readUTF(); System.out.println(string); socket.close(); serverSocket.close(); }
这个会出现什么问题?客户端正连着呢,啪,你服务器给人家断开了,并且accept()接受的是socket请求,因此这种状况,除非客户端再连一次,不然两者的通讯就断了。
你可能会说,那我把Socket移到外面呢?
其实吧,这个仔细理一下就会明白,若是放到外面的话,只要你想接收多个socket,就要把
Socket socket = serverSocket.accept();放到while循环中,可是你只要把它放到while循环中,它就只能和一个socket进行通讯。这里有兴趣能够再查阅一下资料,下面直接进入线程阶段。
import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; public class MyServer { public static void main(String[] args) throws Exception{ ServerSocket serverSocket = new ServerSocket(8852); System.out.println("Server 等待接收数据~"); while(true) { Socket socket = serverSocket.accept();
//这里来一个链接请求就让deal去处理,本身在这里等下一个链接请求 deal(socket); } } public static void deal(Socket client){
//这里建立了一个新的线程 new Thread(new Runnable() { @Override public void run() { DataInputStream dataInputStream=null; DataOutputStream dataOutputStream = null; String receiveFromClient=""; try { dataInputStream = new DataInputStream(client.getInputStream()); dataOutputStream = new DataOutputStream(client.getOutputStream()); //只是这个线程中一直while循环,不影响其余的线程。 while(true) { receiveFromClient = dataInputStream.readUTF(); System.out.println("receive: "+receiveFromClient); if(receiveFromClient.equals("bye")) { dataOutputStream.writeUTF("终于厌倦我了吗?客户端都是大猪蹄子!!"); dataOutputStream.flush(); break; } else { dataOutputStream.writeUTF("你TM给我发 "+receiveFromClient+" 干什么?"); dataOutputStream.flush(); } } }catch (Exception e) { e.printStackTrace(); }finally { try { dataInputStream.close(); dataOutputStream.close(); client.close(); } catch (IOException e) { e.printStackTrace(); } } } }).start(); } }
客户端代码:
import java.io.BufferedReader; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.InputStreamReader; import java.net.Socket; public class MyClient { public static void main(String[] args) throws Exception{ Socket socket = new Socket("127.0.0.1",8852); DataOutputStream dataOutputStream = new DataOutputStream(socket.getOutputStream()); DataInputStream dataInputStream = new DataInputStream(socket.getInputStream()); BufferedReader bReader = new BufferedReader(new InputStreamReader(System.in)); String string; while(true) { string=bReader.readLine(); dataOutputStream.writeUTF(string); System.out.println(dataInputStream.readUTF()); dataOutputStream.flush(); if(string.equals("bye")) break; } socket.close(); } }
结果展现:
服务器端:
客户端: