黑马程序员----JAVA基础之GUI可视化编程与枚举&网络编程



                                                            ------ android培训java培训、期待与您交流! ----------


一、GUI可视化编程

1. GUI可视化编程是什么?

就是让界面可视,点击触发事件

2. GUI可视化编程有什么用?

java程序用一个窗口界面直观的表示所操作的动作和结果,操作更方便

3. GUI的布局
A:流式布局
B:边界布局
C:网格布局
D:网格包布局
E:卡片布局管

4. GUI的事件处理机制

       三个重要的概念:

            A:事件: 用户对组件的一个操作,称之为一个事件。

             B:事件源: 发生事件的组件就是事件源

             C:事件处理器:某个java类中的负责处理时间的成员方法

 一般,我们把某个组件添加一个事件监听.当他产生了某个事件的时候,就会按照对应的处理去执行.


    事件分类:

            MouseEvent   WindowEvent  ActionEvent

 

    处理发生在某个GUI组件上的XxxEvent时间的某个情况,其事件处理的通用编写流程:

     1.       编写一个实现了XxxListenener接口的时间监听类

      2.       XxxListener类中的用于处理该事件情况的方法中,编写处理代码

      3.       调用组建的AddXxxListener方法,将类Xxxlistener创建的实力注册到GUI组建上


5. GUI可视化编程怎么用?

格式:步骤

建立窗口---建立各种组件(菜单,文本框,文本域)-----添加各种组件----给各种组件添加监听器-----给组件添加事件处理

private Frame f;
private TextField tf;
private Button bt, bt1;
private TextArea ta;
private MenuBar mb;
private Menu m, m1;
private MenuItem mi,mi1,mi2,mi3,mi4;
public MyFormat() {
init();
}
private void init() {
// 建立一个窗口
f = new Frame();
//设置窗口名称
f.setTitle("不会回来");
// 设大小位置
f.setBounds(400, 300, 400, 300);
// 设制布局--流式布局
f.setLayout(new FlowLayout());
//建立一个文本框
tf = new TextField(20);
//建立一个按键
bt = new Button("输入");
//再建立一个按键
bt1 = new Button("打印");
//建立一个文本域
ta = new TextArea(10, 40);
//建立一个菜单栏
mb = new MenuBar();
//建立一个菜单
m = new Menu("文件");
//再建立一个菜单
m1 = new Menu("更改标题");
//建立菜单项
mi = new MenuItem("退出系统");
mi1 = new MenuItem("记事本");
mi2 = new MenuItem("好好学习");
mi3 = new MenuItem("天天向上");
mi4 = new MenuItem("恢复标题");
//将菜单栏添加到窗口上
f.setMenuBar(mb);
//将菜单添加至菜单栏
mb.add(m);
//再将菜单项添加至菜单m
m.add(m1);
m.add(mi);
m.add(mi1);
//再给m1添加菜单项
m1.add(mi2);
m1.add(mi3);
m1.add(mi4);
//给窗口添加文本框
f.add(tf);
//给窗口添加按钮
f.add(bt);
f.add(bt1);
//给窗口添加文本域
f.add(ta);
//建立监听方法
myEvent();
//让窗口可见
f.setVisible(true);
}
private void myEvent(){
//给窗口添加关闭事件
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
//给菜单项mi添加事件
mi.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
//给菜单项添加事件
mi1.addActionListener(new ActionListener() {
//给mi2建立事件
public void actionPerformed(ActionEvent e) {
Runtime r =Runtime.getRuntime();
try {
r.exec("notepad");
f.setVisible(false);
System.exit(0);
} catch (IOException e1) {
e1.printStackTrace();
}
}
});
//给文本框添加事件
bt.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
//让文本框写入到文件中
PrintWriter pw =null;
try {
 pw = new PrintWriter(new FileWriter("Frame.txt",true),true);
pw.println(tf.getText());
} catch (IOException e1) {
e1.printStackTrace();
}finally{
if (pw!=null) {
pw.close();
//写完之后清空文本框
tf.setText("");
}
}
}
});
//设立文本域事件
bt1.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
//让文本域据接收数据
//写前之清空文本框
ta.setText("");
BufferedReader br=null;
try {
 br= new BufferedReader(new FileReader("Frame.txt"));
try {
String s=null;
System.out.println(s);
while ((s=br.readLine())!=null) {
ta.append(s+"\t\n");
}
} catch (IOException e1) {
e1.printStackTrace();
}
} catch (FileNotFoundException e1) {
e1.printStackTrace();
}finally{
if (br!=null) {
try {
br.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}
});
}
}



二、枚举


1. 什么是枚举?

枚举是一个特殊的java,用关键字enum表示,不用class,其构造函数私有化,里面提供固定的对象也就是枚举.声名多少个枚举,就有多少个对象.也就是在外部无法再创建这个类的对象,只能用其提供的对象.

底层就是私用化构造方法,并定义几个 public static final 修饰的对象,外部直接用类名打点调对象名获取对象,对象名就是枚举.

2. 枚举有什么用?

枚举可以限定外部能使用的类的对象,从而提高了程序的安全性.并简化代码

3. 枚举怎么用?

外部直接用类名打点调获取对象,并调用类成员:Print.A.print()

1. 声名不带构造方法的枚举

enum Print{

 A,B,C;

}

1.声名带构造的枚举

enum Print{

 A("a"),B("a"),C("a");

String s;

private Test(String s){

this.s=s;

}

}

2.定义带抽象方法的枚举,多用于让枚举实现不同的返回值.

enum Print {

A {

String print() {

return "A";

}

},B {

String print() {

return "B";

}

};

abstract String print();

}

2. 枚举常用特有方法:

 String name() 返回此枚举常量的名称,在其枚举声明中对其进行声明。 如:Print.A.name()=="A";

int ordinal() 返回枚举常量的索引(它在枚举声明中的位置,其中初始常量序数为零)。 

public static <T extends Enum<T>> T valueOf(Class<T> enumType,String name)

返回带指定名称的指定枚举类型的枚举常量。名称必须与在此类型中声明枚举常量所用的标识符完全匹配。(不允许使用额外的空白字符。) 

参数:

enumType - 要从中返回常量的枚举类型的 Class 对象

name - 要返回的常量名称 

返回:带指定名称的指定枚举类型的枚举常量 (枚举类和其)

例如String s = "B";

//下面两种都可以.

Print a = Print.valueOf(Print.class, s);

 a = Print.valueOf(s);

4. 枚举什么时候用?

当需要让一个类只提供固定的对象的时候.

5. 枚举有什么特点?

1.枚举构造方法必须私有

2.声名枚举,必须在类里的首行,枚举间用逗号隔开,如果还有其它代码则最后一个枚举后必须加分号

3.枚举有类的特性,可以声名属性和方法,也可以实现接口和继承抽象类.

4.JDK1.5后,swith可以接收枚举类型

5.如果枚举只有一个值时,可以当单例用.



其实在 java 的枚举实现,这些枚举值还是与某个整形常量值对应的


//枚举类DownloadStatus代码
public enum DownloadStatus {
Remote_File_Noexist, //远程文件不存在
Local_Bigger_Remote, //本地文件大于远程文件
Download_From_Break_Success, //断点下载文件成功
Download_From_Break_Failed, //断点下载文件失败
Download_New_Success, //全新下载文件成功
Download_New_Failed; //全新下载文件失败
} 比如这代码


 三 . 网络编程

1. 什么是网络编程?

就是用来实现网络互连的不同计算机上运行的程序间可以进行数据交换。

2. 网络编程有什么作用?

可以计算机之间相互通信,并进行数据传输

3. 网络编程怎么用?

InetAddress类的使用:

没有构造方法,但可以通过getLocalHost etByName 获取对象

要掌握的功能

获取本地主机:getLocalHost

InetAddress address =InetAddress.getLocalHost();

获取任意指定主机:getByName

InetAddress address = InetAddress.getByName("fada-PC");

主机Ip地址:getHostAddress

String ip = address.getHostAddress();

主机名:getHostName

String name = address.getHostName();

UDP传输:

格式步骤:

DatagramSocket与DatagramPacket

建立发送端,接收端。

建立数据包。

调用Socket的发送接收方法。

关闭Socket

发送端与接收端是两个独立的运行程序。

做一个发送端:

//建立发送端
DatagramSocket ds = new DatagramSocket();
//建立字节输入流并用转换流转换成一个字符缓冲
BufferedReaderbr = new BufferedReader(new InputStreamReader(System.in));
//把字符流中的数据读出 
String s =null;
while((s=br.readLine())!=null){
if("886".equals(s)){
byte[] bye = s.getBytes();
//把字符流读出的数据存在数据包中 建立数据包
break;
}
byte[] bye = s.getBytes();
//把字符流读出的数据存在数据包中建立数据包
DatagramPacket dp = new DatagramPacket(bye,bye.length,InetAddress.getByName("fada-pc"),11118);
//把数据包发送出去
ds.send(dp);
}
//关闭资源
ds.close();
br.close(); 
接收端:
//给定建立接收端
DatagramSocket ds = new DatagramSocket(11118);
//建立一个给定容量的数据包
while(true){
byte[] bye =new byte[1024];
DatagramPacket dp = new DatagramPacket(bye,bye.length);
//将数据包加载到缓存中
ds.receive(dp);
//解析数据包中的IP
String ip = dp.getAddress().getHostAddress();
//解析数据包中的数组接收的内容
String text = new String(bye,0,dp.getLength());
System.out.println(ip+"***"+text);
}


TCP传输

①使用Socket和ServerSocket,

②建立客户端和服务器端,

③建立连接后,通过Socket中的IO流进行数据的传输

④关闭socket

客户端与服务器端也是两个独立的应用程序。

a.TCP协议的客户端

思路:

1:建立客户端的Socket服务,并明确要连接的服务器。

2:如果连接建立成功,就表明,已经建立了数据传输的通道.就可以在该通道通过IO进行数据的读取和写入.

  该通道称为Socket流,Socket流中既有读取流,也有写入流.

3:通过Socket对象的方法,可以获取这两个流

4:通过流的对象可以对数据进行传输

5:如果传输数据完毕,关闭资源

代码:

Socket s = new Socket("192.168.1.34", 10010);
OutputStream os = s.getOutputStream();
os.write("Hello,Tcp,I am coming".getBytes());
s.close();


b.TCP协议的服务器端

思路:

1:建立服务器端的socket服务,需要一个端口

2:服务端没有直接流的操作,而是通过accept方法获取客户端对象,在通过获取到的客户端对象的流和客户端进行通信

3:通过客户端的获取流对象的方法,读取数据或者写入数据

4:如果服务完成,需要关闭客户端,然后关闭服务器,但是,一般会关闭客户端,不会关闭服务器,因为服务端是一直提供服务的

代码:

ServerSocket ss = new ServerSocket(10010);
Socket s = ss.accept();
String ip = s.getInetAddress().getHostAddress();
System.out.println("客户端的ip:"+ip + "*连接上");
InputStream is = s.getInputStream();
byte[] bys = new byte[1024];
int len = is.read(bys);
String text = new String(bys, 0, len);
System.out.println(text);
ss.close();


c.TCP协议的程序服务器给客户端一个反馈

客户端和服务器端在原有的基础上添加反馈,接收端的部分写到客户端下边,客户端的部分写到接收端下边

d.一个大写的转换服务器

客户端代码:

Socket s = new Socket("192.168.1.34", 10086);
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
BufferedReader brServer = new BufferedReader(new InputStreamReader(s.getInputStream()));
String line = null;
while ((line = br.readLine()) != null) {
if ("over".equals(line)) {
break;
}
bw.write(line+"\r\n");
bw.flush();
String serverText = brServer.readLine();
System.out.println("server:" + serverText);
}
br.close();
s.close();


注意:

1.字符流是有缓冲区的,每次数据写入后,需要刷新缓冲区。

2.这样操作后发现还是不行,那么还有什么原因呢?

3.考虑readLine的特点。一次读取一行。但是不要忽略它的结束条件是:\r\n

服务器代码:

ServerSocket ss = new ServerSocket(10086);
Socket s = ss.accept();
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
String line = null;
while ((line = br.readLine()) != null) {
System.out.println(line);
bw.write(line.toUpperCase()+"\r\n");
bw.flush();
}
ss.close();


e.用PrintWriter改写转换服务器

注意println和true的使用

4. 网络编程什么时候用?

计算机间需要进行数据传输时

5. 网络编程有什么特点?

网络通信三要素

IP地址:InetAddress :网络中设备的标识,不易记忆,可用主机名

端口号 :用于标识进程的逻辑地址,不同进程的标识

物理端口 网卡口

逻辑端口 我们指的就是逻辑端口

A:每个网络程序都会至少有一个逻辑端口

B:用于标识进程的逻辑地址,不同进程的标识

C:有效端口:0~65535,其中0~1024系统使用或保留端口。自已定义一般在1万以上

通过360可以查看端口号

传输协议:通讯的规则 ---常见协议:TCPUDP

UDP

将数据源和目的封装成数据包中,不需要建立连接;每个数据报的大小在限制在64k;因无连接,是不可靠协议;不需要建立连接,速度快

TCP

建立连接,形成传输数据的通道;在连接中进行大数据量传输;通过三次握手完成连接,是可靠协议;必须建立连接,效率会稍低

Socket

用于描述IP地址和端口,是一个通信链的句柄。在Internet上的主机一般运行了多个服务软件,同时提供几种服务。每种服务都打开一个Socket,并绑定到一个端口上,不同的端口对应于不同的服务。

Socket就是为网络编程提供的一种机制;通信的两端都有Socket;网络通信其实就是Socket间的通信;数据在两个Socket间通过IO传输。


                                                              ------ android培训java培训、期待与您交流! ----------




                                                            ------ android培训java培训、期待与您交流! ----------


一、GUI可视化编程

1. GUI可视化编程是什么?

就是让界面可视,点击触发事件

2. GUI可视化编程有什么用?

java程序用一个窗口界面直观的表示所操作的动作和结果,操作更方便

3. GUI的布局
A:流式布局
B:边界布局
C:网格布局
D:网格包布局
E:卡片布局管

4. GUI的事件处理机制

       三个重要的概念:

            A:事件: 用户对组件的一个操作,称之为一个事件。

             B:事件源: 发生事件的组件就是事件源

             C:事件处理器:某个java类中的负责处理时间的成员方法

 一般,我们把某个组件添加一个事件监听.当他产生了某个事件的时候,就会按照对应的处理去执行.


    事件分类:

            MouseEvent   WindowEvent  ActionEvent

 

    处理发生在某个GUI组件上的XxxEvent时间的某个情况,其事件处理的通用编写流程:

     1.       编写一个实现了XxxListenener接口的时间监听类

      2.       XxxListener类中的用于处理该事件情况的方法中,编写处理代码

      3.       调用组建的AddXxxListener方法,将类Xxxlistener创建的实力注册到GUI组建上


5. GUI可视化编程怎么用?

格式:步骤

建立窗口---建立各种组件(菜单,文本框,文本域)-----添加各种组件----给各种组件添加监听器-----给组件添加事件处理

private Frame f;
private TextField tf;
private Button bt, bt1;
private TextArea ta;
private MenuBar mb;
private Menu m, m1;
private MenuItem mi,mi1,mi2,mi3,mi4;
public MyFormat() {
init();
}
private void init() {
// 建立一个窗口
f = new Frame();
//设置窗口名称
f.setTitle("不会回来");
// 设大小位置
f.setBounds(400, 300, 400, 300);
// 设制布局--流式布局
f.setLayout(new FlowLayout());
//建立一个文本框
tf = new TextField(20);
//建立一个按键
bt = new Button("输入");
//再建立一个按键
bt1 = new Button("打印");
//建立一个文本域
ta = new TextArea(10, 40);
//建立一个菜单栏
mb = new MenuBar();
//建立一个菜单
m = new Menu("文件");
//再建立一个菜单
m1 = new Menu("更改标题");
//建立菜单项
mi = new MenuItem("退出系统");
mi1 = new MenuItem("记事本");
mi2 = new MenuItem("好好学习");
mi3 = new MenuItem("天天向上");
mi4 = new MenuItem("恢复标题");
//将菜单栏添加到窗口上
f.setMenuBar(mb);
//将菜单添加至菜单栏
mb.add(m);
//再将菜单项添加至菜单m
m.add(m1);
m.add(mi);
m.add(mi1);
//再给m1添加菜单项
m1.add(mi2);
m1.add(mi3);
m1.add(mi4);
//给窗口添加文本框
f.add(tf);
//给窗口添加按钮
f.add(bt);
f.add(bt1);
//给窗口添加文本域
f.add(ta);
//建立监听方法
myEvent();
//让窗口可见
f.setVisible(true);
}
private void myEvent(){
//给窗口添加关闭事件
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
//给菜单项mi添加事件
mi.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
//给菜单项添加事件
mi1.addActionListener(new ActionListener() {
//给mi2建立事件
public void actionPerformed(ActionEvent e) {
Runtime r =Runtime.getRuntime();
try {
r.exec("notepad");
f.setVisible(false);
System.exit(0);
} catch (IOException e1) {
e1.printStackTrace();
}
}
});
//给文本框添加事件
bt.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
//让文本框写入到文件中
PrintWriter pw =null;
try {
 pw = new PrintWriter(new FileWriter("Frame.txt",true),true);
pw.println(tf.getText());
} catch (IOException e1) {
e1.printStackTrace();
}finally{
if (pw!=null) {
pw.close();
//写完之后清空文本框
tf.setText("");
}
}
}
});
//设立文本域事件
bt1.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
//让文本域据接收数据
//写前之清空文本框
ta.setText("");
BufferedReader br=null;
try {
 br= new BufferedReader(new FileReader("Frame.txt"));
try {
String s=null;
System.out.println(s);
while ((s=br.readLine())!=null) {
ta.append(s+"\t\n");
}
} catch (IOException e1) {
e1.printStackTrace();
}
} catch (FileNotFoundException e1) {
e1.printStackTrace();
}finally{
if (br!=null) {
try {
br.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}
});
}
}



二、枚举


1. 什么是枚举?

枚举是一个特殊的java,用关键字enum表示,不用class,其构造函数私有化,里面提供固定的对象也就是枚举.声名多少个枚举,就有多少个对象.也就是在外部无法再创建这个类的对象,只能用其提供的对象.

底层就是私用化构造方法,并定义几个 public static final 修饰的对象,外部直接用类名打点调对象名获取对象,对象名就是枚举.

2. 枚举有什么用?

枚举可以限定外部能使用的类的对象,从而提高了程序的安全性.并简化代码

3. 枚举怎么用?

外部直接用类名打点调获取对象,并调用类成员:Print.A.print()

1. 声名不带构造方法的枚举

enum Print{

 A,B,C;

}

1.声名带构造的枚举

enum Print{

 A("a"),B("a"),C("a");

String s;

private Test(String s){

this.s=s;

}

}

2.定义带抽象方法的枚举,多用于让枚举实现不同的返回值.

enum Print {

A {

String print() {

return "A";

}

},B {

String print() {

return "B";

}

};

abstract String print();

}

2. 枚举常用特有方法:

 String name() 返回此枚举常量的名称,在其枚举声明中对其进行声明。 如:Print.A.name()=="A";

int ordinal() 返回枚举常量的索引(它在枚举声明中的位置,其中初始常量序数为零)。 

public static <T extends Enum<T>> T valueOf(Class<T> enumType,String name)

返回带指定名称的指定枚举类型的枚举常量。名称必须与在此类型中声明枚举常量所用的标识符完全匹配。(不允许使用额外的空白字符。) 

参数:

enumType - 要从中返回常量的枚举类型的 Class 对象

name - 要返回的常量名称 

返回:带指定名称的指定枚举类型的枚举常量 (枚举类和其)

例如String s = "B";

//下面两种都可以.

Print a = Print.valueOf(Print.class, s);

 a = Print.valueOf(s);

4. 枚举什么时候用?

当需要让一个类只提供固定的对象的时候.

5. 枚举有什么特点?

1.枚举构造方法必须私有

2.声名枚举,必须在类里的首行,枚举间用逗号隔开,如果还有其它代码则最后一个枚举后必须加分号

3.枚举有类的特性,可以声名属性和方法,也可以实现接口和继承抽象类.

4.JDK1.5后,swith可以接收枚举类型

5.如果枚举只有一个值时,可以当单例用.



其实在 java 的枚举实现,这些枚举值还是与某个整形常量值对应的


//枚举类DownloadStatus代码
public enum DownloadStatus {
Remote_File_Noexist, //远程文件不存在
Local_Bigger_Remote, //本地文件大于远程文件
Download_From_Break_Success, //断点下载文件成功
Download_From_Break_Failed, //断点下载文件失败
Download_New_Success, //全新下载文件成功
Download_New_Failed; //全新下载文件失败
} 比如这代码


 三 . 网络编程

1. 什么是网络编程?

就是用来实现网络互连的不同计算机上运行的程序间可以进行数据交换。

2. 网络编程有什么作用?

可以计算机之间相互通信,并进行数据传输

3. 网络编程怎么用?

InetAddress类的使用:

没有构造方法,但可以通过getLocalHost etByName 获取对象

要掌握的功能

获取本地主机:getLocalHost

InetAddress address =InetAddress.getLocalHost();

获取任意指定主机:getByName

InetAddress address = InetAddress.getByName("fada-PC");

主机Ip地址:getHostAddress

String ip = address.getHostAddress();

主机名:getHostName

String name = address.getHostName();

UDP传输:

格式步骤:

DatagramSocket与DatagramPacket

建立发送端,接收端。

建立数据包。

调用Socket的发送接收方法。

关闭Socket

发送端与接收端是两个独立的运行程序。

做一个发送端:

//建立发送端
DatagramSocket ds = new DatagramSocket();
//建立字节输入流并用转换流转换成一个字符缓冲
BufferedReaderbr = new BufferedReader(new InputStreamReader(System.in));
//把字符流中的数据读出 
String s =null;
while((s=br.readLine())!=null){
if("886".equals(s)){
byte[] bye = s.getBytes();
//把字符流读出的数据存在数据包中 建立数据包
break;
}
byte[] bye = s.getBytes();
//把字符流读出的数据存在数据包中建立数据包
DatagramPacket dp = new DatagramPacket(bye,bye.length,InetAddress.getByName("fada-pc"),11118);
//把数据包发送出去
ds.send(dp);
}
//关闭资源
ds.close();
br.close(); 
接收端:
//给定建立接收端
DatagramSocket ds = new DatagramSocket(11118);
//建立一个给定容量的数据包
while(true){
byte[] bye =new byte[1024];
DatagramPacket dp = new DatagramPacket(bye,bye.length);
//将数据包加载到缓存中
ds.receive(dp);
//解析数据包中的IP
String ip = dp.getAddress().getHostAddress();
//解析数据包中的数组接收的内容
String text = new String(bye,0,dp.getLength());
System.out.println(ip+"***"+text);
}


TCP传输

①使用Socket和ServerSocket,

②建立客户端和服务器端,

③建立连接后,通过Socket中的IO流进行数据的传输

④关闭socket

客户端与服务器端也是两个独立的应用程序。

a.TCP协议的客户端

思路:

1:建立客户端的Socket服务,并明确要连接的服务器。

2:如果连接建立成功,就表明,已经建立了数据传输的通道.就可以在该通道通过IO进行数据的读取和写入.

  该通道称为Socket流,Socket流中既有读取流,也有写入流.

3:通过Socket对象的方法,可以获取这两个流

4:通过流的对象可以对数据进行传输

5:如果传输数据完毕,关闭资源

代码:

Socket s = new Socket("192.168.1.34", 10010);
OutputStream os = s.getOutputStream();
os.write("Hello,Tcp,I am coming".getBytes());
s.close();


b.TCP协议的服务器端

思路:

1:建立服务器端的socket服务,需要一个端口

2:服务端没有直接流的操作,而是通过accept方法获取客户端对象,在通过获取到的客户端对象的流和客户端进行通信

3:通过客户端的获取流对象的方法,读取数据或者写入数据

4:如果服务完成,需要关闭客户端,然后关闭服务器,但是,一般会关闭客户端,不会关闭服务器,因为服务端是一直提供服务的

代码:

ServerSocket ss = new ServerSocket(10010);
Socket s = ss.accept();
String ip = s.getInetAddress().getHostAddress();
System.out.println("客户端的ip:"+ip + "*连接上");
InputStream is = s.getInputStream();
byte[] bys = new byte[1024];
int len = is.read(bys);
String text = new String(bys, 0, len);
System.out.println(text);
ss.close();


c.TCP协议的程序服务器给客户端一个反馈

客户端和服务器端在原有的基础上添加反馈,接收端的部分写到客户端下边,客户端的部分写到接收端下边

d.一个大写的转换服务器

客户端代码:

Socket s = new Socket("192.168.1.34", 10086);
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
BufferedReader brServer = new BufferedReader(new InputStreamReader(s.getInputStream()));
String line = null;
while ((line = br.readLine()) != null) {
if ("over".equals(line)) {
break;
}
bw.write(line+"\r\n");
bw.flush();
String serverText = brServer.readLine();
System.out.println("server:" + serverText);
}
br.close();
s.close();


注意:

1.字符流是有缓冲区的,每次数据写入后,需要刷新缓冲区。

2.这样操作后发现还是不行,那么还有什么原因呢?

3.考虑readLine的特点。一次读取一行。但是不要忽略它的结束条件是:\r\n

服务器代码:

ServerSocket ss = new ServerSocket(10086);
Socket s = ss.accept();
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
String line = null;
while ((line = br.readLine()) != null) {
System.out.println(line);
bw.write(line.toUpperCase()+"\r\n");
bw.flush();
}
ss.close();


e.用PrintWriter改写转换服务器

注意println和true的使用

4. 网络编程什么时候用?

计算机间需要进行数据传输时

5. 网络编程有什么特点?

网络通信三要素

IP地址:InetAddress :网络中设备的标识,不易记忆,可用主机名

端口号 :用于标识进程的逻辑地址,不同进程的标识

物理端口 网卡口

逻辑端口 我们指的就是逻辑端口

A:每个网络程序都会至少有一个逻辑端口

B:用于标识进程的逻辑地址,不同进程的标识

C:有效端口:0~65535,其中0~1024系统使用或保留端口。自已定义一般在1万以上

通过360可以查看端口号

传输协议:通讯的规则 ---常见协议:TCPUDP

UDP

将数据源和目的封装成数据包中,不需要建立连接;每个数据报的大小在限制在64k;因无连接,是不可靠协议;不需要建立连接,速度快

TCP

建立连接,形成传输数据的通道;在连接中进行大数据量传输;通过三次握手完成连接,是可靠协议;必须建立连接,效率会稍低

Socket

用于描述IP地址和端口,是一个通信链的句柄。在Internet上的主机一般运行了多个服务软件,同时提供几种服务。每种服务都打开一个Socket,并绑定到一个端口上,不同的端口对应于不同的服务。

Socket就是为网络编程提供的一种机制;通信的两端都有Socket;网络通信其实就是Socket间的通信;数据在两个Socket间通过IO传输。


                                                              ------ android培训java培训、期待与您交流! ----------


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值