网络通信的三要素:
1. IP: 设备的标识
2. 端口号: 进程间共同的标识
3. 传输协议:
UDP协议: 面向无连接,数据被封装(在64k以内),不可靠(速度快)。 运用实例: 聊天
TCP协议 : 面向连接,建立双方数据通道,需要三次握手,可靠(速度慢)。运用实例: 打电话
简单的说:UDP以包形式发送数据,但是不可靠,可能会丢包。TCP以流形式发送数据,可靠,但是效率慢
Socket通信实际上就是网络通信,在通信双方两头都有socket,以包/流形式发送数据。
*简单聊天程序:该案例是PC端和服务器进行通信
*发和收同时进行,需要用多线程线,一个线程控制发,一个线程控制收
public class book16{
public static void main(String[] args) throws SocketException {
DatagramSocket sendsocket=new DatagramSocket();
DatagramSocket receivesocket=new DatagramSocket(1001); //根据端口来接受
new Thread(new send(sendsocket)).start();
new Thread(new receive(receivesocket)).start();
}
}
class send implements Runnable{
private DatagramSocket ds;
public send( DatagramSocket ds){
this.ds=ds;
}
public void run() {
try{
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
String s=null;
while((s=br.readLine())!=null) {
if(s.equals("886")){
break;
}
byte[] b=s.getBytes();
//将数据封装到包里,除了数据外,还有IP,端口号
DatagramPacket dp=new DatagramPacket(b, b.length,InetAddress.getByName("123.12.2.12"),1001);
ds.send(dp);
}
}
catch (Exception e){
throw new RuntimeException("发送失败");
}
}
}
class receive implements Runnable{
private DatagramSocket ds;
public receive(DatagramSocket ds){
this.ds=ds;
}
public void run() {
try {
while(true){
byte[] b=new byte[1024];
DatagramPacket dp=new DatagramPacket(b, b.length);
ds.receive(dp); //阻塞式方法
int i=dp.getPort();
String s=dp.getAddress().getHostAddress();
System.out.println(i+"\n"+s);
}
}
catch (Exception e){
throw new RuntimeException("接受失败");
}
}
}
TCP的案例: 发送图片到服务器
* 客户端并发传图片
public class book16{
public static void main(String[] args) {
try {
//数组含有一个参数即图片时,大小为1
if (args.length!=1){
System.out.println("选择一个jpg格式的图片");
return ;
}
File f=new File(args[0]); //根据主函数传值来选定图片
if(!(f.exists()&&f.isFile())){
System.out.println("文件不存在");
return ;
}
if(!f.getName().endsWith(".jpg")){
System.out.println("文件格式不对");
return ;
}
Socket s=new Socket("123.123.2.123",1001);
FileInputStream fs=new FileInputStream(f);
OutputStream os=s.getOutputStream();
byte[] b=new byte[1024];
int i=0;
while((i=fs.read(b))!=-1) {
os.write(b);
}
s.shutdownOutput();
InputStream is=s.getInputStream();
byte[] B=new byte[1024];
int I=is.read(B);
System.out.println(new String(B,0,I));
fs.close();
s.close();
}
catch (Exception e)
{
// TODO: handle exception
}
}
}
//服务端同时接受多个客户端,利用线程封装
public class book16{
public static void main(String[] args) {
try {
ServerSocket ss=new ServerSocket(1001);
while(true){
Socket s=ss.accept();
new Thread( new THREAD(s) ).start();
}
}
catch (IOException e){
}
}
}
class THREAD implements Runnable{
private Socket s;
public THREAD(Socket s) {
this.s=s;
}
public void run() {
String ip=s.getInetAddress().getHostAddress();
int count=1;
try {
System.out.println(ip+"链接");
InputStream is=s.getInputStream();
File f=new File(ip+"("+count+")"+".jpg");
while( f.exists() ){
f=new File(ip+(count++)+".jpg");
}
FileOutputStream fs=new FileOutputStream(f);
byte[] b=new byte[1024];
int i=0;
while((i=is.read(b))!=-1){
fs.write(b,0,i);
}
OutputStream os=s.getOutputStream();
os.write("上传成功".getBytes());
is.close();
s.close();
}
catch (Exception e) {
}
}
}