java---socket编程之服务器端
一开始不懂就自己琢磨了好久,socket是分服务端和客户端两个部分组成,服务器端用seversocket来申请端口,通过accept来接收客户端的请求,客户端用socket(ip,port)来向服务器申请通信.
之间的通信呢,主要是getinputstream(),getoutputstream().两个方法,就像两个人打电话,建立线路之后,第一个人说的话发送给了服务器,服务器再把他发给第二个人一样的道理,
做的是一个简单的聊天客户端,服务器端代码如下,其中遇到的问题
1.单例化操作
2.accept是阻塞线程的方法
3.readline和read都是阻塞的方法
等等,代码里面涉及了一些socket初学会遇到的问题
启动代码:
/**
* 服务器端的代码
* @author li
*
*/
public class demo {
public static void main(String[] args) {
new serverlistener().start();
}
}
sever监听代码:
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import javax.swing.JOptionPane;
public class serverlistener extends Thread {
@Override
public void run() {
try {
//从api来看,这里对serversocket变量需要申请端口,从此端口通信
ServerSocket serverSocket = new ServerSocket(12345);
//while循环是用来不停地监听信道
while(true){
//accept是阻塞方法,会阻塞当前线程,直到接受了新的数据
Socket socket = serverSocket.accept();
JOptionPane.showConfirmDialog(null, "有客户端连接到端口12345");
//把监听到的每一个socket放到子线程,从而达到多个通信
chatsocket cs = new chatsocket(socket);
cs.start();
//单例化操作的方法
chatmanage.getinstance().add(cs);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
socket代码:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.Socket;
public class chatsocket extends Thread {
Socket socket;
public chatsocket(Socket socket) {
this.socket = socket;
}
public void out(String out) {
try {
//通过socket来进行输出,并设置为UTF-8的编码
//readline会阻塞当前线程,所以在服务器端加一个换行符取消阻塞
socket.getOutputStream().write((out+"\n").getBytes("UTF-8"));
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
System.out.println("断开了一个客户端链接");
chatmanage.getinstance().remove(this);
e.printStackTrace();
}
}
@Override
public void run() {
//这句话会被客户端读取到,然后客户端再来输出
out("你已经连接到本服务器了");
try {
//这样的结构使得逻辑很清晰
BufferedReader br = new BufferedReader(
new InputStreamReader(
socket.getInputStream(),"UTF-8"));
String line = null;
//这里的read是会阻塞当前线程的,解决方法在上面out里面
while((line = br.readLine())!=null){
//单例化的操作
chatmanage.getinstance().publish(this, line);
}
br.close();
System.out.println("断开了一个客户端链接");
chatmanage.getinstance().remove(this);
} catch (IOException e) {
System.out.println("断开了一个客户端链接");
chatmanage.getinstance().remove(this);
e.printStackTrace();
}
}
// public static String getContent(BufferedReader br){
// try{
// return br.readLine();
// }
// catch(IOException e){
// }
// return null;
// }
}
socket管理的代码
import java.net.Socket;
import java.util.Vector;
public class chatmanage {
/*
* 设计模式之饿汉式单例模式
* 优点线程安全 缺点不管使不使用都会占用资源
*/
private chatmanage(){};
private static final chatmanage cm = new chatmanage();
public static chatmanage getinstance() {
return cm;
}
Vector<chatsocket> vector = new Vector<chatsocket>();
public void add(chatsocket socket) {
vector.add(socket);
}
public void remove(chatsocket socket) {
vector.remove(socket);
}
/**
* 利用此方法,进行socket之间的通信
* @param cs
* @param out
*/
public void publish(chatsocket cs,String out) {
for (int i = 0; i < vector.size(); i++) {
chatsocket chatsocket = vector.get(i);
if (!cs.equals(chatsocket)) {
chatsocket.out(out);
}
}
}
}
版权声明:本文为博主原创文章,未经博主允许不得转载。