需求:TCP上传图片。
客户端:
1. 服务端点。
2. 读取客户端已有的图片数据。
3. 通过socket输出流将数据发给服务端。
4. 读取服务端反馈信息。
5. 关闭。
import java.io.*;
import java.net.*;
class PicClient
{
public static void main(String[] args) throws Exception
{
Socket s = new Socket("10.10.133.60", 10007);
FileInputStream fis = new FileInputStream("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();
}
}
服务端:
import java.io.*;
import java.net.*;
class PicServer
{
public static void main(String[] args) throws Exception
{
ServerSocket ss = new ServerSocket(10007);
Socket s = ss.accept();
InputStream in = s.getInputStream();
FileOutputStream fos = new FileOutputStream("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();
}
}
如果服务端里面加上while(true),可以多次上传图片,但是这个服务端有个局限性,当A客户端连接上以后,被服务端获取到,服务端执行具体流程,这时B客户端连接,只有等待。因为服务端还没有处理完A客户端的请求,还没有循环回来执行下一次accept方法,所以暂时获取不到B客户端对象。
那么为了可以让多个客户端同时并发访问服务端,那么服务端最好就是将每个客户端封装到一个单独的线程中,这样就可以同时处理多个客户端请求。
如何定义线程呢?
只要明确了每一个客户端要在服务端执行的代码即可,将该代码存入run方法中。
客户端:实现上传格式必须是jpg图片,文件大小限制在5M, 传入文件路径。
import java.io.*;
import java.net.*;
class PicClient
{
public static void main(String[] args) throws Exception
{
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)//文件大小不能超过5M
{
System.out.println("文件过大");
return;
}
Socket s = new Socket("10.10.133.60", 10007);
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();
}
}
服务端:实现并发处理多个客户端请求,如果文件重复上传,则自动改文件名。
import java.io.*;
import java.net.*;
class PicThread implements Runnable
{
private Socket s;
PicThread(Socket s)
{
this. s = s;
}
public void run()
{
int count = 1;
String ip = s.getInetAddress().getHostAddress();
try
{
System.out.println(ip+"...connenct");
InputStream in = s.getInputStream();
File file = new File(ip+"("+(count)+")"+".jpg");
while(file.exists())
file = new File(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);
}
OutputStream out = s.getOutputStream();
out.write("上传成功".getBytes());
fos.close();
s.close();
}
catch (Exception e)
{
throw new RuntimeException(ip+"上传失败");
}
}
}
class PicServer
{
public static void main(String[] args) throws Exception
{
ServerSocket ss = new ServerSocket(10007);
while(true)
{
Socket s = ss.accept();
new Thread(new PicThread(s)).start();
}
//ss.close();
}
}
运行截图:
需求:客户端通过键盘录入用户名,服务端对这个用户名进行校验。
如果该用户存在,在服务端显示xxx,已登录。
并在客户端显示 xxx,欢迎光临
如果用户不存在,在服务端显示xxx,尝试登陆
并在客户端显示xxx,该用户不存在。
每个ip最多可登陆三次。
客户端:
import java.io.*;
import java.net.*;
class LoginClient
{
public static void main(String[] args) throws Exception
{
Socket s = new Socket("10.10.133.60", 10008);
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 x = 0; x <o 3; x ++)
{
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();
}
}
服务端:
import java.io.*;
import java.net.*;
class UserThread implements Runnable
{
private Socket s;
UserThread(Socket s)
{
this.s = s;
}
public void run()
{
String ip = s.getInetAddress().getHostAddress();
try
{
System.out.println(ip+"...connected");
for(int x = 0; x < 3; x ++)
{
BufferedReader bufIn = new BufferedReader(
new InputStreamReader(s.getInputStream()));
String name = bufIn.readLine();
if(name == null)
break;
PrintWriter out = new PrintWriter(
s.getOutputStream(), true);
//校验用户名是否存在
BufferedReader bufr = new BufferedReader(
new FileReader("user.txt"));
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+"校验失败");
}
}
}
class LoginServer
{
public static void main(String[] args) throws Exception
{
ServerSocket ss = new ServerSocket(10008);
while(true)
{
Socket s = ss.accept();
new Thread(new UserThread(s)).start();
}
}
}
运行截图:
演示客户端和服务端。
1.
客户端:浏览器
服务端:自定义
服务端:
import java.net.*;
import java.io.*;
class ServerDemo
{
public static void main(String[] args) throws Exception
{
ServerSocket ss = new ServerSocket(11000);
Socket s = ss.accept();
System.out.println(s.getInetAddress().getHostAddress());
PrintWriter out = new PrintWriter(
s.getOutputStream(), true);
out.println("客户端你好");
s.close();
ss.close();
}
}
在浏览器输入:10.10.133.60:11000
显示:
2.
客户端:浏览器
服务器:Tomcat服务器
3.
客户端:自定义
服务器:Tomcat服务器
URL对象
String getFile() 获取此URL的文件名
String getHost() 获取此URL的主机名(如果使用)
String getPath() 获取此URL的路径部分
int getPort() 获取此URL的端口号
String getProtoco() 获取此URL的协议名称
import java.net.*;
class URLDemo
{
publicstatic void main(String[] args) throws MalformedURLException
{
URLurl = new URL("http://192.168.1.254:8080/myweb/demo.html?name=sr");
System.out.println("getProtocal():"+ url.getProtocol());
System.out.println("getHost():"+ url.getHost());
System.out.println("getPort():"+ url.getPort());
System.out.println("getPath():"+ url.getPath());
System.out.println("geFile():"+ url.getFile());
System.out.println("getQuery():"+ url.getQuery());
//如果不写端口号port默认返回-1,手动设置为80
//http://192.168.1.254/myweb/demo.html?name=sr
//intport = url.getPort();
//if(port== -1)
//port=80;
}
}
URLConnection对象
import java.io.*;
class URLConnectionDemo
{
public static void main(String[] args) throws Exception
{
//URL url = new URL("http://192.168.1.254:8080/myweb/demo.html");
URL url = new URL("http://www.baidu.com");
URLConnection conn = url.openConnection();
//System.out.println(conn);
InputStream in = conn.getInputStream();
byte[] buf = new byte[1024];
int len = 0;
StringBuilder sb = new StringBuilder();
while((len = in.read(buf)) != -1)
{
sb.append(new String(buf, 0, len));
}
System.out.println(sb);
}
}
读到了指定网址的页面源代码
Socket在传输层,URLConnection在应用层