Java实现简单的socket通信

原创 2013年12月05日 00:32:39

前言

首先,说一件无关的事情,萧鼎的诛仙2更新了,这一等就是一年啊,今天中午思考去阿里用神马花名的时候想起来google一下诛仙二,结果50多章都没看过,555,没忍住一下午全用来看小说了,罪过罪过

其次,就是今天学习了一下java如何实现socket通信,感觉难点反而是在io上,因为java对socket封装已经很完善了


参考

学习了一篇博客,写的不错,推荐给大家:http://cs.lmu.edu/~ray/notes/javanetexamples/#capitalize


代码

今天代码花了整个晚上调试,主要原因是io的flush问题和命令行下如何运行具有package的类,不过最后问题基本都解决了,把代码贴出来供大家参考

server

package socket;

import java.io.*;
import java.net.*;

public class TcpServer {
    public static void main(String[] args) throws Exception {
        ServerSocket server = new ServerSocket(9091);
        try {
            Socket client = server.accept();
            try {
                BufferedReader input =
                        new BufferedReader(new InputStreamReader(client.getInputStream()));
                boolean flag = true;
                int count = 1;

                while (flag) {
                    System.out.println("客户端要开始发骚了,这是第" + count + "次!");
                    count++;
                    
                    String line = input.readLine();
                    System.out.println("客户端说:" + line);
                    
                    if (line.equals("exit")) {
                        flag = false;
                        System.out.println("客户端不想玩了!");
                    } else {
                        System.out.println("客户端说: " + line);
                    }

                }
            } finally {
                client.close();
            }
            
        } finally {
            server.close();
        }
    }
}

client

package socket;

import java.io.*;
import java.net.*;
import java.util.Scanner;

public class TcpClient {
    public static void main(String[] args) throws Exception {
        Socket client = new Socket("127.0.0.1", 9091);
        try {
            PrintWriter output =
                    new PrintWriter(client.getOutputStream(), true);
            Scanner cin = new Scanner(System.in);
            String words;

            while (cin.hasNext()) {
                words = cin.nextLine();

                output.println(words);

                System.out.println("写出了数据: " + words);
            }

            cin.close();
        } finally {
            client.close();
        }
    }
}


Server绑定ip

用c写socket的时候,struct sockaddr_in 结构体是可以指定sin_addr.s_addr的,也就是可以指定ip地址,为什么会有这种需求呢,例如我的网络链接是这样的:



我可能只想绑定eth0这个网卡的ip地址,因为我的lo和wlan0都可能在用一端口做了nginx的虚拟主机,因此在服务器端开启ServerSocket的时候,有指定ip的需求


方案

ServerSocket的一个构造函数如下:

public ServerSocket(int port, int backlog, InetAddress bindAddr) throws IOException

参数:
  • port - 本地 TCP 端口
  • backlog - 侦听 backlog
  • bindAddr - 要将服务器绑定到的 InetAddress

因为InetAddress无构造函数,我在这里纠结了好一段时间,查看stackoverflow上,可以使用InetAddress的getByName方法

示例代码

InetAddress bindip = InetAddress.getByName("192.168.1.168");

ServerSocket server = new ServerSocket(9091, 0, bindip);


并发访问

服务器端通过增加多线程来同时处理多个客户端的请求,其实实现还是很水的,毕竟java对多线程封装也足够好了,我是在Server服务器端用一个内部类实现了Runnable接口,在run方法里处理客户端的请求,将数据打印出来

server代码

package capitalsocket;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;

public class CapitalizeServer {
    private static int clientNum = 0;

    public static void main(String args[]) throws Exception {
        ServerSocket listener = new ServerSocket(9898, 0, InetAddress.getByName("192.168.1.168"));
        try {
            while (true) {
                Capitalizer multip = new Capitalizer(listener.accept(), CapitalizeServer.clientNum ++);
                Thread t = new Thread(multip);
                t.start();
            }
        } finally {
            listener.close();
        }
    }

    private static class Capitalizer implements Runnable {
        private Socket client;
        private int id;

        public Capitalizer(Socket s, int id) {
            this.client = s;
            this.id = id;
        }

        public void run() {
            try {
                BufferedReader input =
                        new BufferedReader(new InputStreamReader(this.client.getInputStream()));
                
                while (true) {
                    String data = input.readLine();
                    
                    if (data.equals("bye")) {
                        System.out.println("当前第" + this.id + "个客户端度不想玩了!");
                        break;
                    } else {
                        System.out.println("当前第" + this.id + "个客户端说:" + data);
                    }
                }

            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    this.client.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

}

client代码

客户端代码基本没变,增加了一个退出操作

package capitalsocket;

import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;

public class CapitalizeClient {
    public static void main(String[] args) throws Exception {
        Socket client = new Socket("192.168.1.168", 9898);
        try {
            PrintWriter output = new PrintWriter(client.getOutputStream(), true);
            Scanner cin = new Scanner(System.in);
            String words;

            while (cin.hasNext()) {
                words = cin.nextLine();
                output.println(words);
                
                if (words.equals("bye")) {
                    break;
                }
                
                // 每写一次数据需要sleep一会
                Thread.sleep(3000);
            }

            cin.close();
        } finally {
            client.close();
        }
    }
}


吐槽

java的io还是有点复杂的,蛋疼
版权声明:本文为博主原创文章,未经博主允许不得转载。

关于java通信的一个简单聊天系统的实现

1.客户端类 import java.awt.FlowLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionL...
  • actionzh
  • actionzh
  • 2016年11月17日 00:27
  • 4137

PHP socket实现和Java端readFully对接

java:DataInputStream stream = new DataInputStream(new BufferedInputStream(socket.getInputStream()));...
  • guotong1988
  • guotong1988
  • 2016年03月21日 14:04
  • 1004

利用Java实现网络通信

利用Java实现网络通信吕昱  计算机通过TCP/UDP协议在网络上通信是建立在以下四层模型之上的:  当我们编写JAVA应用程序时,主要是在第四层即应用层工作。一般说来,不必关心TCP/UDP层,这...
  • gnodiah
  • gnodiah
  • 2001年04月27日 16:24
  • 2717

Java实现服务器和客户端简单通信

Java中网络编程这一块有封装的类库,使用简单,了解原理可以教容易实现服务器和客户端的简单通信。在编程之前,首先要需要对TCP/IP协议有一定的了解,需要知道Socket套接字的作用以及用法,这个可以...
  • superxiaolong123
  • superxiaolong123
  • 2017年04月13日 21:40
  • 1216

Java中利用socket实现简单的服务端与客户端的通信(入门级)

Java编程中,要想要使用网络通信,就离不开Socket编程,在此对socket进行简单的介绍。首先声明,这是一个入门级的介绍,仅仅简单的实现了客户端向服务端发送数据,服务端正常的接收数据,当接收到特...
  • qq_25352981
  • qq_25352981
  • 2015年11月19日 18:15
  • 4291

Java中利用socket实现简单的服务端与客户端的通信(基础级)

在上一篇文章中,简单的介绍了java中入门级的socket编程,简单的实现了客户端像服务器端发送数据,服务器端将数据接收并显示在控制台,没有涉及多线程。上一篇文章的链接:Java中利用socket实现...
  • qq_25352981
  • qq_25352981
  • 2015年11月25日 18:41
  • 1345

用JAVA实现网络通信

  • 2010年04月12日 21:56
  • 23KB
  • 下载

java实现最简单socket通讯

一.服务器public class HServerApp implements Runnable { public int port; public HServerApp(int por...
  • hspingcc
  • hspingcc
  • 2017年01月13日 16:07
  • 962

Java socket通信实例,简单入门socket实例代码

是不是看了许多socket入门知识,却还是不能实际运用呢,这篇文章通过利用简单实例程序讲解通过socket实现客户端与服务器之间的通讯。这篇文章可以让你不需要了解socket原理也能利用,便于应急,但...
  • xxxtai
  • xxxtai
  • 2016年08月05日 12:42
  • 4005

Java 实现基于 UDP 的简单 socket 通信

实现基于UDP的简单 socket 通信
  • w_yunlong
  • w_yunlong
  • 2016年01月31日 17:13
  • 2162
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Java实现简单的socket通信
举报原因:
原因补充:

(最多只允许输入30个字)