TCP通信:
面向连接,可靠通信
创建客户端程序,使用Socket类
Socket:
public Socket(String host, int port)
Creates a stream socket and connects it to the specified port number on the named host.
根据指定的服务器ip,端口号请求与服务端建立连接,连接通过,就可以获得客户端socket
public OutputStream getOutputStream()
获取字节输出流对象
public InputStream getInputStream()
获取字节输入流对象
public class client {
public static void main(String[] args) throws Exception{
//创建一个Socket对象,并同时请求与服务端程序连接
//Socket cli=new Socket(InetAddress.getLocalHost().getHostAddress(),8888);
Socket cli=new Socket("127.0.0.1",8888);
//通过Socket对象获取字节输出流
OutputStream out = cli.getOutputStream();
//包装原始输出流
DataOutputStream Dout = new DataOutputStream(out);
Dout.writeUTF("你好");
//关闭
Dout.close();
cli.close();
}
}
创建服务端,使用ServerSocket类
ServerSocket:
public ServerSocket(int port)
Creates a server socket, bound to the specified port.
为服务器程序注册端口
public Socket accept()
Listens for a connection to be made to this socket and accepts it.
阻塞等待客户端的连接请求,一旦与某个客户端连接成功,则返回服务端的Socket对象,用于与客户端进行通信
获取客户端的IP地址,可以调用Socket类中的public SocketAddress getRemoteSocketAddress()方法
public class server {
public static void main(String[] args) throws Exception{
//创建一个ServerSocket对象
ServerSocket ser=new ServerSocket(8888);
//accept阻塞,等待连接
Socket cli = ser.accept();
//获取字节输入流
InputStream in = cli.getInputStream();
//包装原始的输入流
DataInputStream Din = new DataInputStream(in);
String s = Din.readUTF();
System.out.println(s);
//获取客户端的IP地址
System.out.println(cli.getRemoteSocketAddress());
//关闭
Din.close();
ser.close();
}
}public class server {
public static void main(String[] args) throws Exception{
//创建一个ServerSocket对象
ServerSocket ser=new ServerSocket(8888);
//accept阻塞,等待连接
Socket cli = ser.accept();
//获取字节输入流
InputStream in = cli.getInputStream();
//包装原始的输入流
DataInputStream Din = new DataInputStream(in);
String s = Din.readUTF();
System.out.println(s);
//获取客户端的IP地址
System.out.println(cli.getRemoteSocketAddress());
//关闭
Din.close();
ser.close();
}
}
实现多发多收:
客户端:
public class client {
public static void main(String[] args) throws Exception{
//创建一个Socket对象,并同时请求与服务端程序连接
//Socket cli=new Socket(InetAddress.getLocalHost().getHostAddress(),8888);
Socket cli=new Socket("127.0.0.1",8888);
//通过Socket对象获取字节输出流
OutputStream out = cli.getOutputStream();
//包装原始输出流
DataOutputStream Dout = new DataOutputStream(out);
Scanner sa=new Scanner(System.in);
while(true)
{
String s=sa.nextLine();
if(Objects.equals(s,"exit"))
{
//关闭
Dout.close();
cli.close();
break;
}
Dout.writeUTF(s);
Dout.flush();
}
}
}
服务端:
public class server {
public static void main(String[] args) throws Exception {
//创建一个ServerSocket对象
ServerSocket ser = new ServerSocket(8888);
//accept阻塞,等待连接
Socket cli = ser.accept();
//获取字节输入流
InputStream in = cli.getInputStream();
//包装原始的输入流
DataInputStream Din = new DataInputStream(in);
while (true) {
try {
String s = Din.readUTF();
System.out.println(s);
//获取客户端的IP地址
System.out.println(cli.getRemoteSocketAddress());
} catch (IOException e) {//一旦客户端关闭,就会抛异常
System.out.println(cli.getRemoteSocketAddress()+"关闭");
Din.close();
ser.close();
break;
}
}
//关闭
}
}
实现多线程服务器:
任务类:
public class task implements Runnable {
private Socket socket;
public task(Socket socket)
{
this.socket=socket;
}
@Override
public void run() {
//通过socket获取字节输入流
DataInputStream Din = null;
try {
InputStream in = socket.getInputStream();
Din = new DataInputStream(in);
while (true) {
String s = null;
try {
s = Din.readUTF();
} catch (IOException e) {//如果客户端关闭会发送异常
System.out.println(socket.getRemoteSocketAddress()+"关闭");
socket.close();
Din.close();
break;
}
System.out.println(socket.getRemoteSocketAddress() + "客户端发来的数据是" + s);
}
}catch (IOException e) {
throw new RuntimeException(e);
}
}
}
服务器:
public class pthreadServer {
public static void main(String[] args) throws Exception{
//创建一个ServerSocket对象
ServerSocket ser=new ServerSocket(8888);
while(true)
{
Socket socket = ser.accept();//获取Socket对象
new Thread(new task(socket)).start();
System.out.println(socket.getRemoteSocketAddress()+"连接成功");
}
}
}
结果:
实现群聊功能,一个客户端发消息,其他客户端也可以收到消息
方法:服务器程序用一个集合收集在线的所有客户端socket
服务器:
public class pthreadServer {
//创建一个集合
public static List<Socket>list=new ArrayList<>();
public static Object lock=new Object();
public static void main(String[] args) throws Exception{
//创建一个ServerSocket对象
ServerSocket ser=new ServerSocket(8888);
while(true)
{
Socket socket = ser.accept();//获取Socket对象
new Thread(new task(socket)).start();
synchronized (lock) {
pthreadServer.list.add(socket);
}
System.out.println(socket.getRemoteSocketAddress()+"连接成功");
}
}
}
public class task implements Runnable {
private Socket socket;
public task(Socket socket)
{
this.socket=socket;
}
@Override
public void run() {
//通过socket获取字节输入流
DataInputStream Din = null;
try {
InputStream in = socket.getInputStream();
Din = new DataInputStream(in);
while (true) {
String s = null;
try {
s = Din.readUTF();
//把该消息发送给所有客户端的socket
sendMsg(s);
System.out.println(socket.getRemoteSocketAddress() + "客户端发来的数据是" + s);
} catch (IOException e) {//如果客户端关闭会发送异常
System.out.println(socket.getRemoteSocketAddress()+"关闭");
//把该socket客户端移除集合
synchronized (pthreadServer.lock) {
pthreadServer.list.remove(socket);
}
socket.close();
Din.close();
break;
}
}
}catch (IOException e) {
throw new RuntimeException(e);
}
}
private void sendMsg(String s) throws IOException {
System.out.println("fa");
synchronized (pthreadServer.lock) {
for(Socket socket1:pthreadServer.list)
{
//获取一个字节输出流
OutputStream out = socket1.getOutputStream();
DataOutputStream dout = new DataOutputStream(out);
dout.writeUTF(s);//写数据
dout.flush();
}
}
}
}
客户端
public class client {
public static void main(String[] args) throws Exception{
//创建一个Socket对象,并同时请求与服务端程序连接
//Socket cli=new Socket(InetAddress.getLocalHost().getHostAddress(),8888);
Socket cli=new Socket("127.0.0.1",8888);
new Thread(new clientTask(cli)).start();
//通过Socket对象获取字节输出流
OutputStream out = cli.getOutputStream();
//包装原始输出流
DataOutputStream Dout = new DataOutputStream(out);
Scanner sa=new Scanner(System.in);
while(true)
{
String s=sa.nextLine();
if(Objects.equals(s,"exit"))
{
//关闭
Dout.close();
cli.close();
break;
}
Dout.writeUTF(s);
Dout.flush();
}
}
}
public class clientTask implements Runnable{
private Socket socket;
public clientTask(Socket socket)
{
this.socket=socket;
}
@Override
public void run() {
//通过socket获取字节输入流
DataInputStream Din = null;
try {
InputStream in = socket.getInputStream();
Din = new DataInputStream(in);
while (true) {
String s = null;
try {
s = Din.readUTF();
System.out.println(s);
} catch (IOException e) {//自己关闭连接或者服务器关闭连接,就会异常
System.out.println("自己关闭或者服务器关闭");
socket.close();
Din.close();
break;
}
System.out.println(socket.getRemoteSocketAddress() + "客户端发来的数据是" + s);
}
}catch (IOException e) {
throw new RuntimeException(e);
}
}
}