您的位置:首页 > 理论基础 > 计算机网络

Java基础之网络编程知识点总结

2014-12-01 22:00 666 查看
Java语言涵盖的领域很广,对于网络方面,java也是相当棒的,java也是可以完成网络通讯的功能的。想想看,原来我们写出来的java代码都是单机版的,只能一个人在操作,而现在我们想实现这样一个功能,从我的机器上发出一条信息到张三的机器上,然后,张三再给我回复一条信息发到我的机器上。
实际上我们知道数据通讯的原理就是数据的传输的过程。
   网络模型:
      1.OSI参考模型
      2.TCP/IP参考模型
   网络通信要素:
1.  IP地址
2.  端口号
3.  传输协议
试想,要想给张三通讯首要要做的就是找到张三的那台主机,那么怎么找,通过什么方法完成两台机器的通讯呢?
步骤:1)找到对方的IP
          2)数据要发送到对方指定的应用程序上,为了标识这些应用程序,所以给这些网络应用程序都用数字进行标识,为了方便称呼这个数字,就叫做端口。
注意:这里的端口不是物理机器上的实际的端口,而是逻辑端口。
          3)定义一个通讯规则。这个通讯规则称为协议。
国际组织定义了一个通用的协议--TCP/IP协议。


网络通信的要素:
IP地址:InetAddress
   特点:
       网络中的设备标识。
       不易记忆,但是可用主机名。
       本地回环地址127.0.0.1  主机名localhost。


例子1:获得本机的IP地址和主机名。

package cn.itheima.day06;
import java.net.InetAddress;
import java.net.UnknownHostException;
public class IPDemo {
public static void main(String[] args) throws UnknownHostException {
InetAddress i = InetAddress.getLocalHost();   //getLocalHost()返回本地主机
//System.out.println(i.toString());
//System.out.println("address::"+i.getHostAddress());  //获取IP地址
//System.out.println("name::"+i.getHostName());  //获取主机名
InetAddress ia = InetAddress.getByName("127.0.0.1");
System.out.println("address::"+ia.getHostAddress());  //获取IP地址
System.out.println("name::"+ia.getHostName());  //获取主机名
}
}

端口号:
   特点:
     用于标识进程的逻辑地址。
     有效端口号:0—65535,其中0—1024系统使用或保留端口。
传输协议:通讯的规则。
常见协议:TCP、UDP。
TCP和UDP两者之间的区别:
   UDP:1)将数据及源和目的封装成数据包中,不需要建立连接。
             2)每个数据包的大小要限制在64k内
             3)因无连接,是不可靠协议的。
             4)不需要建立连接,速度快。
        UDP就像生活中去寄包裹类似:物品—包装—贴物流单(填写发送信息:IP+端口)--但是填写的地址可能不存在,所以有可能就丢弃了。
        UDP:飞秋聊天、凌波桌面共享、网络视频会议
   TCP:1)建立连接,形成传输数据的通道。
            2)在连接中进行大数据量传输。
            3)通过三次握手完成连接,是可靠协议。
            4)必须建立连接,效率会稍低。
        TCP就像生活中的打电话:拨号—连接(发连接请求)--连接通路,然后双方说话。
        TCP:在线下载、打电话
Socket:
  Scoket就是为网络服务提供的一种机制。通信的两端都有Socket。网络通信其实就是Socket间的通信。
  数据在两个Socket间通过IO传输。
UDP传输(建立UDP的Socket服务方法):
1)DatagramSocket与DatagramPacket.
2)建立发送端,接收端。
3)建立数据包。
4)调用Socket的发送接收方法。
5)关闭Socket。
注意:发送端和接收端是两个独立的运行程序。

例子2.定义一个Socket的发送端和接收端,用于实现两个程序间的发送消息。
  定义了一个udp的发送端:

package cn.itheima.day06;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
/**
* 通过udp传输方式,讲一段文字数据发送出去。
* 定义了一个udp的发送端。
* @author wl-pc
* 思路:1.建立udpsocket服务。
*       2.要提供数据,并将数据封装到数据包中。
*       3.通过socket服务的发送功能,将数据包发送出去。
*       4.关闭资源
*/
public class UdpSendDemo {
public static void main(String[] args) throws IOException {
//1.创建udp服务,通过DatagramScoket对象。
DatagramSocket ds = new DatagramSocket(8888);
//2.确定数据,并且封装成数据包
byte[] buf = "itheima,hello!".getBytes();
DatagramPacket dp =new DatagramPacket(buf, buf.length,InetAddress.getByName("127.0.0.1"),10000);
//3.通过socket服务,将已有的数据包发送出去,通过send()方法
ds.send(dp);
//关闭资源
ds.close();
}
}


定义了一个udp的接收端:

package cn.itheima.day06;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
/**
* 定义一个应用程序,用于接收Udp协议传输的数据并处理数据。
* @author wl-pc
* 思路:
*     1.定义udpsocket服务。(注意:在定义udp的接收端)通常
*     都会监听一个端口,其实就是给这个接收网络应用程序定义
*     一个数字标识,方便与明确哪些数据过来,该应用程序可以处理。
*     2.定义一个数据包,因为要存储接收到的字节数据,因为数据
*       包对象中,有更多功能可以提取字节数据中的不同数据信息
*     3.通过socket服务的receive()方法接收到数据存入已定义好
*       的数据包中。
*     4.通过数据包对象的特有的功能,将这些不同的数据取出,打
*       印到控制台上
*     5.关闭资源。
*/
public class UdpReceDemo {
public static void main(String[] args) throws IOException {
//1.创建udp的socket服务,建立端点
DatagramSocket ds = new DatagramSocket(10000);
//2.定义数据包,用于存储数据。
byte[] buf = new byte[1024];
DatagramPacket dp =new DatagramPacket(buf, buf.length);
//3.通过服务的的receive()方法将接收到的数据存入数据包中
ds.receive(dp);
//4.通过数据包中的方法获取其中的数据。
String ip = dp.getAddress().getHostAddress();
String data = new String(dp.getData(),0,dp.getLength());
int port = dp.getPort();
System.out.println(ip+"::"+data+"::"+port);
//5.关闭资源
ds.close();
}
}

例子3:聊天小程序
定义了一个udp的发送端:

package cn.itheima.day06;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
/**
* 记着一个规律:在程序中只要用到了java.net包,通常都会用到java.io包。
* @author wl-pc*/
public class UdpSendDemo2 {
public static void main(String[] args) throws IOException {
DatagramSocket ds = new DatagramSocket();
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String line = null;
//readLine()方法是阻塞式方法,如果没有数据,会等
while((line=br.readLine())!=null){
if("886".equals(line))
break;
byte[] buf = line.getBytes();
DatagramPacket dp = new DatagramPacket(buf, buf.length,InetAddress.getByName("127.0.0.1"),10003);
ds.send(dp);
}
ds.close();
}
}

定义了一个udp的接收端:

package cn.itheima.day06;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
public class UdpReceDemo2 {
public static void main(String[] args) throws IOException {
DatagramSocket ds = new DatagramSocket(10003);
while(true){
byte[] buf = new byte[1024];
DatagramPacket dp = new DatagramPacket(buf, buf.length);
ds.receive(dp);  //receive()方法是阻塞式方法,如果没有数据,会等
String ip = dp.getAddress().getHostAddress();
String data = new String(dp.getData(),0,dp.getLength());
int port = dp.getPort();
System.out.println(ip+"::"+data+"::"+port);
}
}
}

例子3:使用多线程的技术完成聊天小程序。(1个进程多个线程)

package cn.itheima.day06;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
/**
* 编写一个聊天程序:
* 有一个接收数据的部分和发送数据的部分,
* 这两个部分需要同时执行,那就要使用到了
* 多线程技术了,一个线程控制接收数据,
* 另一个线程负责发送数据。
* @author wl-pc
* 因为收和发数据的动作时不一致的,所以
* 要定义两个run()方法,而且这两个run()
* 方法要封装到不同的类中。
*/
class Send implements Runnable{
private DatagramSocket ds;
Send(DatagramSocket ds) {
this.ds = ds;
}
@Override
public void run() {
try {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String line = null;
while((line=br.readLine())!=null){
if("886".equals(line))
break;
byte[] buf = line.getBytes();
DatagramPacket dp =new DatagramPacket(buf, buf.length,InetAddress.getByName("127.0.0.1"),10005);
ds.send(dp);
}
} catch (Exception e){
throw new RuntimeException("发送端失败!");
}
}
}
class Rece implements Runnable{
private DatagramSocket ds;
Rece(DatagramSocket ds) {
this.ds = ds;
}
@Override
public void run() {
try {
while(true){
byte[] buf = new byte[1024];
DatagramPacket dp = new DatagramPacket(buf, buf.length);
ds.receive(dp);
String ip =dp.getAddress().getHostAddress();
String data = new String(dp.getData(),0,dp.getLength());
int port = dp.getPort();
System.out.println(ip+"::"+data+"::"+port);
}
} catch (Exception e) {
throw new RuntimeException("接收端失败!");
}
}
}
public class ChatDemo {
public static void main(String[] args) throws SocketException {

DatagramSocket sendSocket = new DatagramSocket();
DatagramSocket receSocket = new DatagramSocket(10005);
new Thread(new Send(sendSocket)).start();
new Thread(new Rece(receSocket)).start();
}
}

TCP传输:
1)Socket和ServerSocket
2)建立客服端和服务器端
3)建立连接后,通过Socket中的IO流进行数据的传输。
4)关闭socket
同样,客户端与服务器端是两个独立的应用程序。

例子4:客户端向服务端发送数据信息。
定义了一个TCP的服务器端:

package cn.itheima.day06;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

/**
* 服务端需求:定义端点接收数据,并且打印到控制台上。
*  步骤:
*      1)建立服务端的socket的服务,通过ServerSocket()来建立,
*         并监听一个端口。
*      2)获取连接过来的客户端对象,通过ServerSocket的accept()
*         方法来完成。所以这个方法是阻塞式的,没有连接,就会等。
*      3)客户端如果发过来数据,那么服务端要使用对应的客户端对象
*         并获取到该客户端对象的读取流来读取的发过来的数据。并打印
*         在控制台上。
*      4)(可选操作)关闭服务端。
*/
public class TcpServer {
public static void main(String[] args) throws IOException{
//1.建立服务端的socket服务,并监听一个端口
ServerSocket ss = new ServerSocket(10006);
//2.通过accept()方法获取连接过来的客户端对象。
Socket s = ss.accept();
String ip = s.getInetAddress().getHostAddress();
System.out.println(ip+"::连接成功!");
//3.获取客户端发送过来的数据,那么要使用客户
//端对象的读取流来读取数据
InputStream in = s.getInputStream();   //源是网络流
byte[] buf = new byte[1024];
int len = in.read(buf);
System.out.println(new String(buf,0,len));
s.close();
ss.close();
}
}

定义了一个TCP的客户端:

package cn.itheima.day06;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
/**
* 演示TCP传输:
* @author wl-pc
* 1.tcp分为客户端和服务器端
* 2.客服端对应的对象是socket
*   服务器端对应的对象是serverSocket
*/
/**
* 客户端:通过查阅socket对象,发现在该
* 对象建立时,就可以连接指定的主机。
* 因为tcp是面向连接的。所以在建立socket服务
* 时,就要有服务端存在,并且连接成功,形成
* 通路后,再在该通道进行数据的传输。
* @author wl-pc
* 步骤:
*    1)创建socket服务,并指定要连接的主机和端口
*    2)为了发送数据,应该获取socket流中的输出流
*    3)往输入流中写数据
*    4)关闭资源
*/
/**
* 需求:给服务端发送一个文本数据
*/
public class TcpClient {
public static void main(String[] args) throws UnknownHostException, IOException {
//1.创建客户端的socket服务,指定目的主机以及端口
Socket s = new Socket("127.0.0.1",10006);
//2.为了发送数据,应该获取socket流中的输出流
OutputStream out = s.getOutputStream();
//3.往流中写数据
out.write("itheima,hello!".getBytes());
//4.关闭资源
s.close();
}
}

例子5:演示tcp的传输的客户端和服务器端的互访。
定义了一个TCP的服务器端:

package cn.itheima.day06;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
/**
* 演示tcp的传输的客户端和服务器端的互访。
* @author wl-pc
*/
public class TcpServer2 {
public static void main(String[] args) throws IOException {
ServerSocket ss = new ServerSocket(10007);
Socket s = ss.accept();
String ip = s.getInetAddress().getHostAddress();
System.out.println(ip+"......conneted");
InputStream in = s.getInputStream();
byte[] buf = new byte[1024];
int len = in.read(buf);
System.out.println(new String(buf,0,len));
OutputStream out = s.getOutputStream();
out.write("收到数据,你也好!".getBytes());
s.close();
ss.close();
}
}

定义了一个TCP的客户端:

package cn.itheima.day06;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
/**
* 演示tcp的传输的客户端和服务器端的互访。
* @author wl-pc
* 需求是:客户端给服务端发送数据,服务器
* 端收到数据后,给客户端反馈信息
*/
/**
* 客户端步骤:
*    1)建立socket服务,指定要连接的主机和端口
*    2)获取socket流中输出流,将数据写到该流中
*       通过网络发送到服务器端
*    3)获取socket流中输入流,将服务端反馈的数
*       据获取到并打印到控制台上
*    4)关闭客户端资源
*/
public class TcpClient2 {
public static void main(String[] args) throws UnknownHostException, IOException {
Socket s = new Socket("127.0.0.1",10007);
OutputStream out =s.getOutputStream();
out.write("服务端,你好".getBytes());
InputStream in = s.getInputStream();
byte[] buf = new byte[1024];
int len = in.read(buf);
System.out.println(new String(buf,0,len));
s.close();
}
}

例子6:建立一个文本转换服务器,客户端给服务器端发送文本,然后服务器端将文件转成大写,再返回给客户端,而且客服端可以不断的进行文本转换,当客户端输入over时转换就结束了。
定义了一个TCP的服务器端:

package cn.itheima.day06;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
/**
* 服务端:
* 源:socket读取流
* 目的:socket输出流
* @author wl-pc
* 都是文本数据并且需要装饰
*/
public class TransServer {
public static void main(String[] args) throws IOException {
ServerSocket ss = new ServerSocket(4002);
Socket s = ss.accept();
String ip = s.getInetAddress().getHostAddress();
System.out.println(ip+"....conneted");
//读取socket读取流中的数据
BufferedReader bufIn =new BufferedReader(new InputStreamReader(s.getInputStream()));
//socket输出流中,并且要转换成大写字母再写入到socket输出流,并发送给客户端
BufferedWriter bufOut = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
String line = null;
while((line=bufIn.readLine())!=null){  //readLine()阻塞式方法
bufOut.write(line.toUpperCase());
bufOut.newLine();  //跨平台换行
bufOut.flush();  //刷新数据
}
s.close();
ss.close();
}
}

定义了一个TCP的客户端:

package cn.itheima.day06;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
/**
* 需求:建立一个文本转换服务器
* 客户端给服务器端发送文本,然后服务器端将文件转成大写
* 再返回给客户端,而且客服端可以不断的进行文本转换,当
* 客户端输入over时转换就结束了
* @author wl-pc
* 分析:
* 客服端:
* 既然是操作设备上的数据,就可以使用IO技术,按照IO的操作
* 规律来思考,对于客服端来讲,源:键盘录入。
* 目的:网络设备(网络输出流),而且操作的是文本数据,
* 是文本数据可以选择字符流,
* 步骤:
*    1)建立服务。
*    2)获取键盘录入。
*    3)将数据发给服务端。(重复操作)
*    4)获取服务端返回的大写数据。(重复操作)
*    5)结束,关闭资源。
* 都是文本数据,可以用字符流进行操作。
* 同时为了提高效率,加入了缓冲技术
*/
public class TransClient {
public static void main(String[] args) throws IOException {
Socket s = new Socket("127.0.0.1",4002);
//定义读取键盘数据的流对象
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
//定义目的,将数据写入到socket输出流中,发给服务端
BufferedWriter bufOut = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
//定义一个socket读取流,读取服务端反馈的大写信息
BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream()));
String line = null;
while((line=bufr.readLine())!=null){
if("over".equals(line))
break;
//往服务器端写入要转换的信息
bufOut.write(line);
bufOut.newLine();
bufOut.flush();  //刷新数据
//读出转换后的大写信息
String str = bufIn.readLine();
System.out.println("server::"+str);
}
bufr.close();
s.close();
}
}
/**
* 该例子出现的问题。
* 现象:客户端和服务端都在莫名的等待,这是为什么?
* 因为客户端和服 务器端都有阻塞式的方法,这些方法没有
* 读到结束标记,那么就一直等,而导致两端,都在等待,
* 解决方法:就查看阻塞式方法的地方,因为这个地方时
* 容易出错的地方。
*/

例子7:上传文件到一个文件夹下。
定义了一个TCP的服务器端:

package cn.itheima.day06;
import java.io.BufferedReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class TextServer {
public static void main(String[] args) throws IOException {
ServerSocket ss = new ServerSocket(4006);
Socket s = ss.accept();
String ip = s.getInetAddress().getHostAddress();
System.out.println(ip+".....conneted");
BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream()));
PrintWriter out = new PrintWriter(new FileWriter("F:\\Javajichu\\JavaLianXi\\src\\cn\\itheima\\day06\\server.txt"),true);
String line = null;
while((line=bufIn.readLine())!=null){
out.println(line);
}
s.shutdownOutput();  //关闭客户端的输出流,相当于给流中加一个结束标记  :-1
PrintWriter pw = new PrintWriter(s.getOutputStream(),true);
pw.println("上传成功!");
out.close();
s.close();
ss.close();
}
}

定义了一个TCP的客户端:

package cn.itheima.day06;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
public class TextClient {
public static void main(String[] args) throws UnknownHostException, IOException {
Socket s = new Socket("127.0.0.1",4006);
BufferedReader bufr = new BufferedReader(new FileReader("F:\\Javajichu\\JavaLianXi\\src\\cn\\itheima\\day06\\client.txt"));
PrintWriter out = new PrintWriter(s.getOutputStream(),true);
//out.println(time);
String line = null;
while((line = bufr.readLine())!=null){
out.println(line);
}
BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream()));
String str = bufIn.readLine();
System.out.println(str);
bufr.close();
s.close();
}
}

例子8:上传图片。
定义了一个TCP的服务器端:

package cn.itheima.day07;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class PicServer {
public static void main(String[] args) throws IOException {
ServerSocket ss = new ServerSocket(4007);
Socket s = ss.accept();
InputStream in = s.getInputStream();
FileOutputStream fos = new FileOutputStream("F:\\Javajichu\\JavaLianXi\\src\\cn\\itheima\\day07\\server.jpg");
byte[] buf = new byte[1024];
int len = 0;
while((len=in.read(buf))!=-1){
fos.write(buf,0,len);
}
OutputStream out = s.getOutputStream();
out.write("上传成功!".getBytes());
fos.close();
s.close();
ss.close();
}
}

定义了一个TCP的客户端:

package cn.itheima.day07;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
/**
* 需求:上传图片
*/
/**
* 客户端:
* 步骤:
*    1)服务端点
*    2)读取客户端已有的一个图像数据
*    3)通过socket输出流将数据发给服务端
*    4)读取服务器端的反馈信息
*    5)关闭资源
*/
public class PicClient {
public static void main(String[] args) throws UnknownHostException, IOException {
Socket s = new Socket("127.0.0.1",4007);
FileInputStream fis = new FileInputStream("F:\\Javajichu\\JavaLianXi\\src\\cn\\itheima\\day07\\1.jpg");
OutputStream out = s.getOutputStream();
byte[] buf = new byte[1024];
int len = 0;
while((len=fis.read(buf))!=-1){
out.write(buf,0,len);
}
s.shutdownOutput(); //告诉客户端数据已经写完
InputStream in =s.getInputStream();
byte[] bufIn = new byte[1024];
int num = in.read(bufIn);
System.out.println(new String(bufIn,0,num));
fis.close();
s.close();
}
}

例子9:改写例子8中的程序,要求多人可以上传图片到服务器端。
定义了一个TCP的服务器端:

package cn.itheima.day07;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
/**
* 这个服务端有个局限性:当A客户连接上时,被服务端获取到,
* 服务端执行具体执行流程,这时B客户连接时,连不上,只有
* 等待,因为服务器端还没有处理完A的请求,还没有循环回来
* 执行下一次的accept()方法,所以暂时获取不到B客户对象。
* @author wl-pc
* 那么为了可以让多个客户端同时并发访问服务端,那么服务端
* 最好是将每个客户端封装到一个单独的线程中,这样,就可以
* 同时处理多个客户端请求。
*
* 那么如何定义线程呢?
* 只要明确了每一个客户端要在服务端执行的代码即可,将代码
* 写在run()方法中即可。
*/
class PicThread implements Runnable{
private Socket s;
PicThread(Socket s) {
this.s=s;
}
@Override
public void run() {
int count = 1;
String ip = s.getInetAddress().getHostAddress();
try {
System.out.println(ip+".....connected");
InputStream in = s.getInputStream();
File file = new File("F:\\Javajichu\\JavaLianXi\\src\\cn\\itheima\\day07\\"+ip+"("+(count)+")"+".jpg");
while(file.exists()){
file = new File("F:\\Javajichu\\JavaLianXi\\src\\cn\\itheima\\day07\\"+ip+"("+(count++)+")"+".jpg");
}
FileOutputStream fos = new FileOutputStream(file);
byte[] buf = new byte[1024];
int len = 0;
while((len=in.read(buf))!=-1){
fos.write(buf,0,len);
fos.flush();
}
OutputStream out = s.getOutputStream();
out.write("上传成功!".getBytes());
fos.close();
s.close();
} catch (Exception e) {
throw new RuntimeException(ip+"上传失败!");
}
}
}
public class PicServer {
public static void main(String[] args) throws IOException {
ServerSocket ss = new ServerSocket(4008);
while(true){  //本意要实现多人上传图片到服务器端(但是此种方法是不可取的)
Socket s = ss.accept(); //accept()是阻塞式方法
new Thread(new PicThread(s)).start();   //利用多线程实现同时上传的功能。
}
//ss.close();
}
}

定义了一个TCP的客户端:

package cn.itheima.day07;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException
/**
* 需求:上传图片
*/
/**
* 客户端:
* 步骤:
*    1)服务端点
*    2)读取客户端已有的一个图像数据
*    3)通过socket输出流将数据发给服务端
*    4)读取服务器端的反馈信息
*    5)关闭资源
*/
public class PicClient {
public static void main(String[] args) throws UnknownHostException, IOException {
if(args.length!=1){
System.out.println("请选择一个jpg格式的图片");
return;
}
File file = new File(args[0]);
if(!file.exists()&&file.isFile()){
System.out.println("该文件有问题,要么是不存在,要么是有问题!");
return;
}
if(!file.getName().endsWith(".jpg")){
System.out.println("图片格式错误,请重新选择!");
return;
}
if(file.length()>1024*1024*5){
System.out.println("上传的文件过大!");
return;
}
Socket s = new Socket("127.0.0.1",4008);
FileInputStream fis = new FileInputStream(file);
OutputStream out = s.getOutputStream();
byte[] buf = new byte[1024];
int len = 0;
while((len=fis.read(buf))!=-1){
out.write(buf,0,len);
}
s.shutdownOutput(); //告诉客户端数据已经写完
InputStream in =s.getInputStream();
byte[] bufIn = new byte[1024];
int num = in.read(bufIn);
System.out.println(new String(bufIn,0,num));
fis.close();
s.close();
}
}


例子10:用户登录的小例子。
需求:客户端通过键盘录入用户名,服务器端对这个用户名进行校验。如果该用户名存在,在服务器端显示xxxx,已登录。并在客户端显示xxx,欢迎光临。如果该用户不存在,在服务器端显示xxxx,尝试登陆。并在客户端显示xxxx,该用户不存在。最多登陆3次,3次后结束。
定义服务器端:

package cn.itheima.day07;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
class UserThread implements Runnable{
private Socket s;
UserThread(Socket s){
this.s = s;
}
@Override
public void run() {
String ip =s.getInetAddress().getHostAddress();
System.out.println(ip+"....conneted");
try {
for(int i=0;i<3;i++){
BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream()));
String name = bufIn.readLine();
if(name==null)
break;
BufferedReader bufr = new BufferedReader(new FileReader("F:\\Javajichu\\JavaLianXi\\src\\cn\\itheima\\day07\\user.txt"));
PrintWriter out =new PrintWriter(s.getOutputStream(),true);
String line = null;
boolean flag = false;
while((line=bufr.readLine())!=null){
if(line.equals(name)){
flag = true;
break;
}
}
if(flag){
System.out.println(name+",已经登陆!");
out.println(name+",欢迎光临");
break;
}else{
System.out.println(name+",尝试登陆!");
out.println(name+",该用户名不存在!");
}
}
s.close();
} catch (Exception e) {
throw new RuntimeException(ip+"校验失败!");
}
}

}
public class LoginServer {
public static void main(String[] args) throws IOException {
ServerSocket ss = new ServerSocket(4013);
while(true){
Socket s = ss.accept();
new Thread(new UserThread(s)).start();
}
}
}

定义客户端:

package cn.itheima.day07;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
/**
* 客户端通过键盘录入用户名
* 服务器端对这个用户名进行校验。
* 如果该用户名存在,在服务器端显示xxxx,已登录。
* 并在客户端显示xxx,欢迎光临。
* 如果该用户不存在,在服务器端显示xxxx,尝试登陆。
* 并在客户端显示xxxx,该用户不存在。
* 最多登陆3次,3次后结束。
* @author wl-pc
*/
public class LoginClient {
public static void main(String[] args) throws UnknownHostException, IOException {
Socket s = new Socket("127.0.0.1",4013);
//用于接收客户端的输入的信息
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
PrintWriter out =new PrintWriter(s.getOutputStream(),true);
//反馈服务器端发来的反馈信息
BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream()));
for(int i=0;i<3;i++){
String line = bufr.readLine();
if(line==null)
break;
out.println(line);
String info = bufIn.readLine();
System.out.println("info:"+info);
if(info.contains("欢迎"))  //包含欢迎字符,就停止
break;
}
bufr.close();
s.close();
}
}

例子11. 客服端用本机上的浏览器,而服务端是自己定义的。

package cn.itheima.day07;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
/**
* 演示:客户端和服务端
* 1.客服端浏览器
*   服务端自定义
* @author wl-pc
*/
public class ServerDemo {
public static void main(String[] args) throws IOException {
ServerSocket ss = new ServerSocket(4016);
Socket s = ss.accept();
String ip = s.getInetAddress().getHostAddress();
System.out.println(ip+".....connected");
PrintWriter out = new PrintWriter(s.getOutputStream(),true);
out.println("客户端你好!");
s.close();
ss.close();
}
}


例子12.自定义IE浏览器。

package cn.itheima.day07;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
public class MyIE {
public static void main(String[] args) throws UnknownHostException, IOException {
Socket s = new Socket("127.0.0.1",8080);
PrintWriter out = new PrintWriter(s.getOutputStream(),true);
out.println("GET /myweb/demo.html HTTP/1.1");
out.println("Accept: */*");
out.println("Accept-Language: zh-CN");
out.println("Host: 127.0.0.1:4016");
out.println("Connection: Keep-Alive");
out.println();
out.println();
BufferedReader bufr = new BufferedReader(new InputStreamReader(s.getInputStream()));
String line = null;
while((line = bufr.readLine())!=null){
System.out.println(line);
}
s.close();
}
}


例子13.URL链接对象

package cn.itheima.day07;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
public class URLConnetctionDemo {
public static void main(String[] args) throws IOException {
URL url = new URL("http://127.0.0.1:8080/myweb/demo.html");
URLConnection conn = url.openConnection();//打开连接。其实内部封装就是Socket
System.out.println(conn);
InputStream in = conn.getInputStream();//其实使用就是Socket类中的getInputStream
byte[] buf = new byte[1024];
int len = in.read(buf);
System.out.println(new String(buf,0,len));
}
}

例子14.自定义GUI的IE浏览器。

import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
class MyWindow
{
private Frame f;
private TextField tf;
private Button but;
private TextArea ta;
MyWindow()
{
init();
}
public void init()
{
f = new Frame("my window");
f.setSize(500,500);
f.setLocation(400,100);
f.setLayout(new FlowLayout());
tf = new TextField(40);
but = new Button("转 到");
ta = new TextArea(25,60);
f.add(tf);
f.add(but);
f.add(ta);
myEvent();
f.setVisible(true);
}
private void myEvent()
{
tf.addKeyListener(new KeyAdapter()
{
public void keyPressed(KeyEvent e)
{
if(e.getKeyCode()==KeyEvent.VK_ENTER)
showWeb();
}
});
but.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
showWeb();
}
});
f.addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
});
}
private void showWeb()
{
String str_url = tf.getText();
try
{
//URI要比URL的范围大
URL url = new URL(str_url);
URLConnection conn = url.openConnection();//打开连接。其实内部封装就是Socket
//System.out.println(conn);
ta.setText("");
InputStream in = conn.getInputStream();//其实使用就是Socket类中的getInputStream
byte[] buf = new byte[1024];
int len = in.read(buf);
ta.append(new String(buf,0,len));
/*
String host = url.getHost();
int port = url.getPort();
String path = url.getPath();
Socket s = new Socket(host,port);
PrintWriter out = new PrintWriter(s.getOutputStream(),true);
out.println("GET "+path+" HTTP/1.1");
out.println("Accept: *");
out.println("Host: 192.168.54.9:8080");
out.println("Connection: close");
out.println();
ta.setText("");
BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream()));
String line = null;
while((line=bufIn.readLine())!=null)
{
ta.append(line+"\r\n");
}
s.close();
*/
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
class MyIEByGUI
{
public static void main(String[] args)
{
new MyWindow();
}
}
//http://192.168.54.9:8080/myweb/1.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息