0%

Java Socket使用

JAVA WEB网络编程

Socket套接字

  • socket使用TCP实现计算机间的通信机制。client创建一个socket,并尝试连接服务器的socket。
  • 客户与服务端可以使用对Socket的读写来实现通信。

    ServerSocket类为服务器提供一种监听客户端并建立连接的机制。
    具体实现:

    1. Server端实例化一个ServerSocket,表示通过服务器上的端口通信。
    2. ServerSocket.accept()方法将一直等待直到客户端连接上服务器的端口
    3. Client端实例化Socket,指定服务器地址与端口号请求连接。
    4. Socket的构造函数尝试连接。通信被建立后,则可通过Socket通信,否则抛出IOException
    5. Server端accept()返回一个scoket引用,该socket连接到Client的Socket
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//TCPServer.class
import java.io.*;
import java.net.*;
public class TCPServer {
public static void main(String[] args) {
int port = 6066;
try {
ServerSocket server = new ServerSocket(port);
System.out.println("等待远程连接,端口号为:" + server.getLocalPort() + "...");
Socket client = server.accept();
System.out.println(client.getRemoteSocketAddress());
//获取输入流
DataInputStream in = new DataInputStream(client.getInputStream());
System.out.println(in.readUTF());
DataOutputStream out = new DataOutputStream(client.getOutputStream());
out.writeUTF("欢迎连接:" + server.getLocalSocketAddress() + "\nGoodbye!");
client.close();
}catch (SocketTimeoutException s){
System.out.println("Time out !");
}catch (IOException e){
e.printStackTrace();
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
//TCPClient.class
import java.io.*;
import java.net.Socket;
public class TCPClient {
public static void main(String[] args) {
String serverName = localhost;
int port = 6066;
try{
System.out.println("连接到主机:" + serverName + ",端口号:" + port);
//尝试连接服务器
Socket client = new Socket(serverName, port);
//获取套接字连接的远程地址
System.out.println("远程主机地址:" + client.getRemoteSocketAddress());
//获取套接字的输出流
OutputStream outToServer = client.getOutputStream();

DataOutputStream out = new DataOutputStream(outToServer);
out.writeUTF("Hello from " + client.getLocalSocketAddress());
//获取套接字输入流
InputStream inFromServer = client.getInputStream();
DataInputStream in = new DataInputStream(inFromServer);
System.out.println("服务器响应: " + in.readUTF());
client.close();
}catch (IOException e){
e.printStackTrace();
}
}
}

Tip : 利用输入输出流传输数据,DataOutputStream(字节流),并且以UTF编码写入。

Web服务器实现

  • Web服务器,使用http与客户端通信。主要包括HttpServer类,Request类,Response类
  • 应用程序的入口在HttpServer类中,main()方法创建一个HttpServer实例,然后调用其await()方法,在指定端口上等待HTTP请求,对其进行处理,然后发送响应信息回客户端,在接收到关闭命令前,它会保持等待状态。
  • 该Web服务器仅发送位于指定目录的静态资源的请求,如html文件和图像,它也可以将传入到的http请求字节流显示到控制台,但不发送任何头信息到浏览器,如日期或者cookies等。
  • 我只简单实现了服务器的代码,请求与响应部分先直接交给浏览器处理。

TIP:
返回客户端时服务器发送的数据:

  1. HTTP/1.0 200 Document Follows(writeBytes)
  2. Content-Type:image/jpg(writeBytes) (解析方式)
  3. Content-Lenght(writeBytes)
  4. 文件 -> write(文件的字节形式, 0, Lenght)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    //HTTPServer.class
    import java.io.*;
    import java.net.*;
    class Server extends Thread{
    private ServerSocket server;
    private String[] msg;
    private String fileName;
    private Server(int post) throws IOException {
    server = new ServerSocket(post);
    msg = new String[5];
    }
    public void run(){
    while(true){
    try{
    Socket client = server.accept();
    BufferedReader read = new BufferedReader(new InputStreamReader(client.getInputStream()));
    msg = read.readLine().split(" ");

    if(msg[0].equals("GET")){
    if(msg[1].startsWith("/"))
    fileName = msg[1].substring(1);
    File f = new File(fileName);
    int lenght = (int) f.length();
    byte[] fileInByte = new byte[lenght];
    FileInputStream fin = new FileInputStream(f);
    fin.read(fileInByte);

    DataOutputStream outputToClient = new DataOutputStream(client.getOutputStream());
    outputToClient.writeBytes("HTTP/1.0 200 Document Follows\r\n");
    outputToClient.writeBytes("Content-Type:image/jpg\r\n");
    outputToClient.writeBytes("Content-Lenght:" + lenght + "\r\n");
    outputToClient.writeBytes("\r\n");
    outputToClient.write(fileInByte, 0, lenght);
    outputToClient.close();
    }else System.out.println("bad request message");
    }catch (SocketTimeoutException e){
    System.out.println("Time out ...");
    break;
    }catch (FileNotFoundException e) {
    System.out.println("bad requset file " + fileName);
    }catch (IOException e){
    e.printStackTrace();
    break;
    }
    }
    }
    public static void main(String[] args) {
    try{
    new Server(6066).start();
    }catch (IOException e){
    e.printStackTrace();
    }
    }
    }

完结 撒花 ฅ>ω<*ฅ