socket(基于TCP协议)

Posted 二九幂加八

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了socket(基于TCP协议)相关的知识,希望对你有一定的参考价值。

1.概念

作用:用于客户端与服务端交互

技术:基于TCP协议的socket传输

端口:在服务端绑定端口号,ServerSocket(端口号)

监听:服务端的accept()方法用于监听是否有客户端访问,该方法时由ServerSocket提供

发送与接受:通过OutputStream、InputStream两个对象,都是通过Socket去获取

关闭:Socket与输入输出流等都需要关闭,使用close()方法

2.发送字符串

(1)服务端

package nuc.hzb.socket;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class MyServer {
   public static void main(String[] args) throws IOException {

       ServerSocket serverSocket = new ServerSocket(9999);
       Socket socket = serverSocket.accept();
       System.out.println("与客户端连接成功!");


       // 服务端向客户端发送消息
       OutputStream out = socket.getOutputStream();
       String info = "hello";
       // String转化为byte[]
       out.write(info.getBytes());

       // 接受客户端发来的消息
       InputStream in = socket.getInputStream();
       byte[] bs = new byte[100] ;
       in.read(bs) ;
       System.out.println("接受客户端发来的消息:" + new String(bs));

       out.close();
       in.close();
       socket.close();
       serverSocket.close();
  }
}

(2)客户端

package nuc.hzb.socket;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;

public class MyClient {
   public static void main(String[] args) throws IOException {

       Socket socket = new Socket("127.0.0.1", 9999);

       // 接受服务端发送的消息InputStream
       InputStream in = socket.getInputStream();
       byte[] bs = new byte[100] ;
       // 读取发送来的数据
       in.read(bs) ;
       // byte[]转化为String
       System.out.println("客户端接受到的消息为:" + new String(bs));

       // 客户端向服务端做出反馈(向服务端发送消息)
       OutputStream out = socket.getOutputStream();
       out.write("world".getBytes());

       out.close();
       in.close();
       socket.close();
  }
}

3.发送文件

(1)服务端

package nuc.hzb.socket;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

public class MyServer {
   public static void main(String[] args) throws IOException {

       ServerSocket serverSocket = new ServerSocket(9999);
       Socket socket = serverSocket.accept();
       System.out.println("与客户端连接成功!");

       // 服务端向客户端发送消息
       OutputStream out = socket.getOutputStream();

       // 准备要发送的文件
       File file = new File("C:\\Users\\黄朝博\\Desktop\\Linux笔记.docx");

       // 将此文件从硬盘读到内存
       FileInputStream fileInputStream = new FileInputStream(file);
       // 定义每次发送文件的大小
       byte[] fileBytes = new byte[200];
       int len = -1;
       // 循环发送
       while ((len = fileInputStream.read(fileBytes)) != -1) {
           System.out.println(len);
           out.write(fileBytes, 0, len);
      }

       fileInputStream.close();
       out.close();
       socket.close();
       serverSocket.close();
  }
}

(2)客户端

package nuc.hzb.socket;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;

public class MyClient {
   public static void main(String[] args) throws IOException {

       Socket socket = new Socket("127.0.0.1", 9999);

       // 接受服务端发送的消息InputStream
       InputStream in = socket.getInputStream();

       FileOutputStream fileOutputStream = new FileOutputStream("D:\\Linux笔记.docx");

       byte[] fileBytes = new byte[200];
       int len = -1;

       while ((len = in.read(fileBytes)) != -1) {
           System.out.println(len);
           fileOutputStream.write(fileBytes, 0, len);
      }

       fileOutputStream.close();
       in.close();
       socket.close();
  }
}

4.多线程优化

(1)MyDownload.java

package nuc.hzb.socket.multithreading;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;

// 处理下载的线程
public class MyDownload implements Runnable {

private Socket socket;

public MyDownload(Socket socket) {
this.socket = socket ;
}

// 线程要做的事情:下载
@Override
public void run() {
try {
System.out.println("与客户端连接成功!");
// 服务端向客户端发送消息Output
OutputStream out = socket.getOutputStream() ;
File file = new File("C:\\Users\\黄朝博\\Desktop\\Linux笔记.docx");
//将此文件从硬盘读入到内存
InputStream fileIn = new FileInputStream(file) ;
byte[] fileBytes = new byte[1000] ; // 定义每次发送的文件大小
int len = -1 ;
// 发送(因为文件较大,不能一次发送完毕,因此需要通过循环来分次发送)
while((len=fileIn.read(fileBytes)) != -1) {
out.write(fileBytes, 0, len);
}
fileIn.close();
out.close();
socket.close();
} catch(Exception e) {
e.printStackTrace();
}

}

}

(2)MyServer.java

package nuc.hzb.socket.multithreading;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class MyServer {
   public static void main(String[] args) throws IOException {
       ServerSocket server = new ServerSocket(9999);
       while(true) {
           Socket socket = server.accept() ;
           // 下载的线程
MyDownload download = new MyDownload(socket) ;
           // Runnable->Thread
Thread downLoadThread = new Thread(download);
downLoadThread.start();
           // 简化
           // new Thread(new MyDownload(socket)).start();
      }
  }
}

(3)MyClient.java

package nuc.hzb.socket.multithreading;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;

public class MyClient {
   public static void main(String[] args) throws IOException {

       Socket socket = new Socket("127.0.0.1", 9999);

       // 接受服务端发送的消息InputStream
       InputStream in = socket.getInputStream();

       FileOutputStream fileOutputStream = new FileOutputStream("D:\\Linux笔记.docx");

       byte[] fileBytes = new byte[200];
       int len = -1;

       while ((len = in.read(fileBytes)) != -1) {
           System.out.println(len);
           fileOutputStream.write(fileBytes, 0, len);
      }

       fileOutputStream.close();
       in.close();
       socket.close();
  }
}

以上是关于socket(基于TCP协议)的主要内容,如果未能解决你的问题,请参考以下文章

C++语言实现网络聊天程序的设计与实现(基于TCP/IP协议的SOCKET编程)超详细(代码+解析)

基于TCP协议的socket套接字编程

基于TCP协议下的socket编程

基于TCP协议的socket编程

Python网络编程02/基于TCP协议的socket简单的通信

socket(基于TCP协议)