publicclass t3_Server {publicstaticvoidmain(String[] args)throwsIOException{finalint port =10000;//绑定10000的端口ServerSocket ss =newServerSocket(port);System.out.println(ss.getInetAddress()+"启动,监听"+ ss.getLocalPort()+"端口");Date d =null;DateFormat df =newSimpleDateFormat("yyyy-MM-dd HH:mm:ss");String time =null;//死循环:多个客户端连接同一服务器while(true){//获得客户端套接字Socket s = ss.accept();System.out.println("获得客户端:"+ s.getRemoteSocketAddress()+"的联接");
d =newDate();
time = df.format(d);//套接字编程的底层是IO,使用输出流(相对当前程序看)try(OutputStream os = s.getOutputStream();){
os.write(time.getBytes());
os.flush();}catch(Exception e){
e.printStackTrace();}System.out.println("服务端断开与客户端的连接");
s.close();}}}
Socket
publicclass t3_Client {publicstaticvoidmain(String[] args)throwsIOException{Socket s =newSocket("localhost",10000);System.out.println("联接成功 "+ s);//使用输入流接收服务端数据try(InputStream in = s.getInputStream()){byte[] b =newbyte[1024];int length =-1;//客户端等待服务端的响应,阻塞式while((length = in.read(b,0, b.length))!=-1){String str =newString(b,0, length);System.out.println("服务端的响应:"+ str);}}catch(Exception e){
e.printStackTrace();}System.out.println("客户端断开与服务端的连接");
s.close();}}
需求2
服务器启动时自动选一个空闲端口
确定传输的是字节流,将其转成字符流以提升性能
ServerSocket
publicclass t4_Server {publicstaticvoidmain(String[] args)throwsIOException{//需求1.自动选一个端口finalint port =10000;//端口固定 会存在端口占用问题ServerSocket ss =null;for(int i =10000; i <65535; i++){//10000以下端口尽量不要占try{
ss =newServerSocket(i);//绑定i的端口break;//注意:端口绑定成功打断循环}catch(Exception e){if(e instanceofBindException){System.out.println("端口:"+ i +"已占用");}}}System.out.println(ss.getInetAddress()+"启动,监听"+ ss.getLocalPort()+"端口");Date d =null;DateFormat df =newSimpleDateFormat("yyyy-MM-dd HH:mm:ss");String time =null;while(true){//获得客户端套接字Socket s = ss.accept();System.out.println("获得客户端:"+ s.getRemoteSocketAddress()+"的联接");
d =newDate();
time = df.format(d);//需求2:将字节流转成字符流以提升性能try(OutputStreamWriter os =newOutputStreamWriter(s.getOutputStream());){
os.write(time);
os.flush();}catch(Exception e){
e.printStackTrace();}System.out.println("服务端断开与客户端的连接");
s.close();}}}
Socket
publicclass t4_Client {publicstaticvoidmain(String[] args)throwsIOException{Socket s =newSocket("localhost",10000);System.out.println("联接成功 "+ s);//需求2:将字节流转成字符流以提升性能try(InputStreamReader in =newInputStreamReader(s.getInputStream())){char[] b =newchar[1024];int length =-1;while((length = in.read(b,0, b.length))!=-1){String str =newString(b,0, length);System.out.println("服务端的响应:"+ str);}}catch(Exception e){
e.printStackTrace();}System.out.println("客户端断开与服务端的连接");
s.close();}}
需求3
一个服务器与一个客户端的聊天
要求客户端先发
ServerSocket
publicclass t5_talkServer {publicstaticvoidmain(String[] args){ServerSocket ss =null;for(int i =10000; i <65535; i++){try{
ss =newServerSocket(i);break;}catch(Exception e){if(e instanceofBindException){System.out.println("端口:"+ i +"被占用");}}}System.out.println("启动:"+ ss.getInetAddress().getHostAddress()+",监听:"+ ss.getLocalPort());//通过键盘录入聊天消息Scanner sc =newScanner(System.in);while(true){try(Socket s = ss.accept();Scanner sn =newScanner(s.getInputStream());PrintWriter pw =newPrintWriter(s.getOutputStream())){System.out.println("客户端:"+ s.getRemoteSocketAddress()+"连上");do{String response = sn.nextLine();System.out.println("客户端:"+ s.getRemoteSocketAddress()+"对server说:"+ response);if("bye".equalsIgnoreCase(response)){System.out.println("服务器主动断开与客户端的连接");break;}System.out.println("输入服务器对客户端"+ s.getRemoteSocketAddress()+"说:");String line = sc.nextLine();
pw.println(line);
pw.flush();if("bye".equalsIgnoreCase(line)){System.out.println("客户端主动断开与服务器的连接");break;}}while(true);System.out.println("服务器与客户端"+ s.getRemoteSocketAddress()+"主动结束聊天");}catch(Exception e){
e.printStackTrace();}}}}
Socket
publicclass t5_talkClient {publicstaticvoidmain(String[] args)throwsIOException{Socket s =newSocket("121.43.226.171",10000);System.out.println("联接成功 "+ s);try(Scanner sc =newScanner(System.in);//键盘录入C话Scanner sn =newScanner(s.getInputStream());//获取服务器的回答PrintWriter pw =newPrintWriter(s.getOutputStream());//客户端的回答){do{System.out.println("客户端对服务器端说:");String line = sc.nextLine();
pw.println(line);
pw.flush();if("bye".equalsIgnoreCase(line)){System.out.println("客户端主动断开与服务器的连接");break;}String response = sn.nextLine();System.out.println("服务器对客户端说:"+ response);if("bye".equalsIgnoreCase(line)){System.out.println("服务器主动断开与客户端的连接");break;}}while(true);System.out.println("在服务器正常结束聊天");}catch(Exception e){
e.printStackTrace();}System.out.println("客户端关闭");
s.close();}}
需求4
一个服务器与n个客户端聊天
引入线程:聊天是耗时操作
ServerSocket
publicclass t6_talkServer_duo {publicstaticvoidmain(String[] args){ServerSocket ss =null;for(int i =10000; i <65535; i++){try{
ss =newServerSocket(i);break;}catch(Exception e){if(e instanceofBindException){System.out.println("端口:"+ i +"被占用");}}}System.out.println("启动:"+ ss.getInetAddress().getHostAddress()+",监听:"+ ss.getLocalPort());Scanner sc =newScanner(System.in);while(true){try{Socket s = ss.accept();//不能写在try()中,否则套接字将被关闭System.out.println("客户端:"+ s.getRemoteSocketAddress()+"连上");TalkTask tt =newTalkTask(s);Thread t =newThread(tt);
t.start();}catch(Exception e){
e.printStackTrace();}}}}classTalkTaskimplementsRunnable{//套接字privateSocket s;Scanner sc =newScanner(System.in);publicTalkTask(Socket s){this.s = s;}@Overridepublicvoidrun(){try{Socket s =this.s;Scanner sn =newScanner(s.getInputStream());PrintWriter pw =newPrintWriter(s.getOutputStream());do{String response = sn.nextLine();System.out.println("客户端:"+ s.getRemoteSocketAddress()+"对server说:"+ response);if("bye".equalsIgnoreCase(response)){System.out.println("服务器主动断开与客户端的连接");break;}System.out.println("输入服务器对客户端"+ s.getRemoteSocketAddress()+"说:");String line = sc.nextLine();
pw.println(line);
pw.flush();if("bye".equalsIgnoreCase(line)){System.out.println("客户端主动断开与服务器的连接");break;}}while(true);System.out.println("服务器与客户端"+ s.getRemoteSocketAddress()+"主动结束聊天");}catch(Exception e){
e.printStackTrace();}}}
编写应用层协议连接百度
1.手工编写
publicclass t7_telent_baidu {publicstaticvoidmain(String[] args){String website ="www.baidu.com";int port =80;//应用层协议String http ="GET / HTTP/1.0\r\nHost: www.baidu.com\r\n\r\n";try(Socket s =newSocket(website, port);OutputStream out = s.getOutputStream();InputStream in = s.getInputStream();){//将协议写到服务端
out.write(http.getBytes());
out.flush();//获取服务端的响应byte[] bytes =newbyte[10*1024];int length =-1;while((length = in.read(bytes,0, bytes.length))!=-1){String str =newString(bytes,0, length);System.out.println(str);}}catch(Exception e){
e.printStackTrace();}}}