Java网络编程基础

两台计算机连接通信

两台计算机进行连接,总有一台服务器,一台客户端。
服务器和客户端之间的通信通过端口进行。
例如:
ip地址是 192.168.1.100的服务器通过端口 8080
与ip地址是192.168.1.189的客户端 的1087端口通信

获取本机ip地址

1
2
3
4
5
6
7
8
9
10
11
12
13
package socket;

import java.net.InetAddress;
import java.net.UnknownHostException;

public class TestSocket {

public static void main(String[] args) throws UnknownHostException {
InetAddress host = InetAddress.getLocalHost();
String ip =host.getHostAddress();
System.out.println("本机ip地址:" + ip);
}
}

Socket进行网络编程

建立连接

Server端:

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
package socket;

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

/**
* @author shaoguoliang
*
*/
public class Server {

public static void main(String[] args){
try {
ServerSocket ss = new ServerSocket(8888); //服务器打开8888端口
System.out.println("The Server is monitoring the port 8888");

Socket socket = ss.accept(); //等待8888端口接收连接请求
System.out.println("There is a Connection coming.");

socket.close();
ss.close();
} catch (IOException e) {
// TODO: handle exception
e.printStackTrace();
}
}
}

Client端

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package socket;

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

/**
* @author shaoguoliang
*
*/
public class Client {
public static void main(String[] args){
try {
Socket socket = new Socket("127.0.0.1", 8888);
System.out.println(socket);
socket.close();
} catch (UnknownHostException e) {
// TODO: handle exception
e.printStackTrace();
} catch (IOException e){
e.printStackTrace();
}
}
}

Tips:

  • 运行分别运行两个java程序,先开Server,再开Client
  • java命令运行class文件,对于含有package的原文件,需要在存放package的根目录执行运行。java socket.Server

传输数据流

Client使用Scanner读取控制台的输入,然后传送一条数据到Server端。

Server端,用DataInputStream来包裹InputStream:

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
package socket;

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

/**
* @author shaoguoliang
*
*/
public class Server {
public static void main(String[] args){
try {
ServerSocket ss = new ServerSocket(8888); //服务器打开8888端口
System.out.println("The Server is monitoring the port 8888");

Socket socket = ss.accept();
System.out.println("There is a Connection coming.");

InputStream is = socket.getInputStream(); //接收inputstream

DataInputStream dis = new DataInputStream(is);

String msg = dis.readUTF();
System.out.println(msg);

dis.close();
socket.close();
ss.close();
} catch (IOException e) {
// TODO: handle exception
e.printStackTrace();
}
}
}

Client端,使用Scanner来读取控制台的输入:

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
package socket;

import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;

/**
* @author shaoguoliang
*
*/
public class Client {

public static void main(String[] args){
try {
Socket socket = new Socket("127.0.0.1", 8888);
System.out.println(socket);

OutputStream os = socket.getOutputStream();
DataOutputStream dos = new DataOutputStream(os);

Scanner sc = new Scanner(System.in);
String str = sc.next();
dos.writeUTF(str);

dos.close();
os.close();
socket.close();
} catch (UnknownHostException e) {
// TODO: handle exception
e.printStackTrace();
} 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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
package socket;

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


/**
* @author shaoguoliang
*
*/
public class ReadRunable implements Runnable{

private Socket socket;
private String orin;
public boolean connection = false;

/**
*
*/
public ReadRunable(Socket socket, String orin, boolean connection) {
// TODO Auto-generated constructor stub
this.socket = socket;
this.orin = orin;
this.connection = connection;
}

/* (non-Javadoc)
* @see java.lang.Runnable#run()
*/
@Override
public void run() {
// TODO Auto-generated method stub
try {
while(connection){
InputStream is = socket.getInputStream();
DataInputStream dis = new DataInputStream(is);
System.out.print(orin + ":\r\n" + dis.readUTF());
}
socket.close();
} catch (IOException e) {
// TODO: handle exception
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
package socket;

import java.io.DataOutputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Scanner;

/**
* @author shaoguoliang
*
*/
public class SendRunable implements Runnable{

private Socket socket;
public Scanner scanner;
public boolean connection = false;

/**
*
*/
public SendRunable(Socket socket, Scanner scanner, boolean connection) {
// TODO Auto-generated constructor stub
this.socket = socket;
this.scanner = scanner;
this.connection = connection;
}

/* (non-Javadoc)
* @see java.lang.Runnable#run()
*/
@Override
public void run() {
// TODO Auto-generated method stub
try {
while(connection){
OutputStream os = socket.getOutputStream();
DataOutputStream dos = new DataOutputStream(os);
String msg = scanner.next();
dos.writeUTF(msg);
}
socket.close();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
}

Client端:

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
package socket;

import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;

/**
* @author shaoguoliang
*
*/
public class ClientContinue {
public static void main(String[] args) throws UnknownHostException, IOException{
Socket socket = new Socket("127.0.0.1", 8888); //必须handle exception
boolean connection = (socket != null);
if(connection){
System.out.println("The connection is successful");
}
Scanner scanner = new Scanner(System.in);

//创造线程,读线程和写线程
Runnable readRunnable = new ReadRunable(socket, "Server", connection);
Runnable sendRunnable = new SendRunable(socket, scanner, connection);

//开启线程
new Thread(readRunnable).start();
new Thread(sendRunnable).start();
}
}

Server端:

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
package socket;

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

/**
* @author shaoguoliang
*
*/
public class ServerContinue {

public static void main(String[] args) throws IOException, InterruptedException{
ServerSocket ss = new ServerSocket(8888); //服务器监听端口8888
System.out.println("Server is monitoring Port 8888");

Socket socket = ss.accept(); //接收socket
boolean connection = (socket!=null);
Scanner scanner = new Scanner(System.in);
Runnable readRunnable = new ReadRunable(socket, "Client", connection);
Runnable sendRunnable = new SendRunable(socket, scanner, connection);

new Thread(readRunnable).start();
new Thread(sendRunnable).start();

while(Thread.activeCount() > 1){
Thread.sleep(1000);
}
ss.close();
}
}