套接字图示
有个需要注意的问题
就像打完电话需要挂断才能打下一个一样,当server给client发完一条消息,要调用输入/输出流的close()方法 来挂断电话才能播出下一通电话。
输入/输出流都是实实在在的硬件,此类操作,都会有相应的clsoe方法进行关闭。
两端都正常关闭的状态称之为orderly,只有一端正常关闭称之为abortive(流产)。会报出"connect reset"的错误。
服务端
public class MsgServer {
/*这个命名和初始化分开的写法就很好
serversocker时成员变量,所以放前面命名比较好看
但是他的初始化需要放在try中,所以在后面初始化*/
private ServerSocket serverSocket=null;
Socket socket[]=new Socket[100];
public void connection(){
try {
serverSocket=new ServerSocket(54321);//创建服务端套接字
//监听
for (int i=0;i<100;i++){
//给个端口号,进行构造
System.out.println("正在监听");
socket[i]=serverSocket.accept();
System.out.println(",客户端口:"+socket[i].getPort());
}
//群发消息
for (int i=0;i<100;i++){
OutputStream os=socket[i].getOutputStream();
String msg="hello,cuihao";
os.write(msg.getBytes());
os.flush();
os.close();
}
}catch (IOException e){
e.printStackTrace();
}
}
public static void main(String[] args){
new MsgServer().connection();
}
}
客户端
public class Client {
private Socket client[]=new Socket[100];
public void setSocket(){
try {
try {
Thread.sleep (500);
} catch (InterruptedException e) {
e.printStackTrace ();
}
for (int i=0;i<100;i++){
client[i]=new Socket("localhost",54321);//new客户端套接字,以链接服务端创建的套接字
System.out.println("服务端端口:"+client[i].getPort());
System.out.println("客户端口:"+client[i].getLocalPort());
}
for (int i=0;i<100;i++){
InputStream IS=client[i].getInputStream();
int msgb=0; //用来存读到的消息
System.out.println("开始读消息");
while (true){
msgb=IS.read(); //这个是一个一个的读
if (msgb==-1){ //read方法读完时,会返回-1
break;
}
System.out.print((char)msgb);
}
client[i].close();
IS.close();
}
}catch (IOException e){
e.printStackTrace();
}
}
public static void main(String[] args){
new Client().setSocket();
}
}