Socket IO工具类:

package com.test.util;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket; public class SocketIO{
public static DataInputStream getInput(Socket socket) throws IOException{
//接收缓存区大小,socket获取输入流之前设置
socket.setReceiveBufferSize(10);
InputStream input = socket.getInputStream();
return new DataInputStream(input);
} public static DataOutputStream getOutput(Socket socket) throws IOException{
//发送缓存区大小,socket获取输出流之前设置
socket.setSendBufferSize(10);
OutputStream output = socket.getOutputStream();
return new DataOutputStream(output);
}
}

如果传输数据量较大,则应配置较大缓存区,以减少数据传输次数,提高数据传输效率

如果传输数据量较小并且比较频繁,则应配置较小缓存,以提高通信速度

Socket Client客户端:

package com.test.client;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress; import org.apache.log4j.Logger; import com.test.util.SocketIO; public class Client {
static Logger logger = Logger.getLogger(Client.class);
private int port = 10000;
private String host = "127.0.0.1";
private Socket socket; public Client(){
try {
socket = new Socket();
//关闭socket时,立即释放socket绑定端口以便端口重用,默认为false
socket.setReuseAddress(true);
//关闭传输缓存,默认为false
socket.setTcpNoDelay(true);
//如果输入流等待1000毫秒还未获得服务端发送数据,则提示超时,0为永不超时
socket.setSoTimeout(10000);
//关闭socket时,底层socket不会直接关闭,会延迟一会,直到发送完所有数据
//等待10秒再关闭底层socket连接,0为立即关闭底层socket连接
socket.setSoLinger(true, 10);
//设置性能参数,可设置任意整数,数值越大,相应的参数重要性越高(连接时间,延迟,带宽)
socket.setPerformancePreferences(3, 2, 1);
SocketAddress address = new InetSocketAddress(host, port);
//socket创建超时时间为1000毫秒
socket.connect(address, 10000); logger.info("client ip:"+socket.getLocalAddress());
logger.info("client port:"+socket.getLocalPort());
logger.info("servetr ip:"+socket.getInetAddress());
logger.info("servetr port:"+socket.getPort());
} catch (IOException e) {
e.printStackTrace();
logger.error("Cilent socket establish failed!");
}
logger.info("Client socket establish success!");
} public void request(){
try{
DataOutputStream output = SocketIO.getOutput(socket);
DataInputStream input = SocketIO.getInput(socket); String question = "your name?";
byte[] bytes = question.getBytes("utf-8");
int len = bytes.length;
output.writeInt(len);
output.write(bytes); len = input.readInt();
bytes = new byte[len];
input.read(bytes); logger.info("server answer:"+new String(bytes,"utf-8"));
}catch(Exception e){
e.printStackTrace();
logger.error("client request error");
}finally{
if(null != socket){
try{
socket.close();
}catch(Exception e){
e.printStackTrace();
logger.error("socket close error");
}
}
}
} public static void main(String[] args){
Client client = new Client();
client.request();
}
}

Socket Server服务端:

package com.test.server;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket; import org.apache.log4j.Logger; import com.test.util.SocketIO; public class Server {
static Logger logger = Logger.getLogger(Server.class);
private int queueSize = 10;
private int port = 10000;
private ServerSocket serverSocket; public Server(){
try{
serverSocket = new ServerSocket();
//关闭serverSocket时,立即释放serverSocket绑定端口以便端口重用,默认为false
serverSocket.setReuseAddress(true);
//accept等待连接超时时间为1000毫秒,默认为0,永不超时
//serverSocket.setSoTimeout(10000);
//为所有accept方法返回的socket对象设置接收缓存区大小,单位为字节,默认值和操作系统有关
serverSocket.setReceiveBufferSize(128*1024);
//设置性能参数,可设置任意整数,数值越大,相应的参数重要性越高(连接时间,延迟,带宽)
serverSocket.setPerformancePreferences(3, 2, 1);
//服务端绑定至端口,10为服务端连接请求队列长度
serverSocket.bind(new InetSocketAddress(port), queueSize);
}catch(Exception e){
e.printStackTrace();
logger.error("Server establish error!");
}
logger.info("Server start up!");
} public void service(){
while(true){
Socket socket = null;
try{
//从连接请求队列中取出一个客户连接请求,创建与客户连接的socket对象
//如果队列中没有请求,accept方法就会一直等待
socket = serverSocket.accept(); DataOutputStream output = SocketIO.getOutput(socket);
DataInputStream input = SocketIO.getInput(socket); int len = input.readInt();
byte[] bytes = new byte[len];
input.read(bytes); String request = new String(bytes, "utf-8"); logger.info("client request:"+request); String answer = "not supported";
if(request.equals("your name?")){
answer = "server";
}
bytes = answer.getBytes("utf-8");
len = bytes.length;
output.writeInt(len);
output.write(bytes);
}catch(Exception e){
e.printStackTrace();
logger.error("Server run exception!");
}
}
} public static void main(String[] args) {
Server server = new Server();
server.service();
}
}

log4j.properties日志设置:

log4j.rootLogger=info,logOutput

#log console out put
log4j.appender.logOutput=org.apache.log4j.ConsoleAppender
log4j.appender.logOutput.layout=org.apache.log4j.PatternLayout
log4j.appender.logOutput.layout.ConversionPattern=%p%d{[yy-MM-dd HH:mm:ss]}[%c] -> %m%n

Client端日志:

INFO[13-10-10 10:04:23][com.test.client.Client] -> client ip:/127.0.0.1
INFO[13-10-10 10:04:23][com.test.client.Client] -> client port:52362
INFO[13-10-10 10:04:23][com.test.client.Client] -> servetr ip:/127.0.0.1
INFO[13-10-10 10:04:23][com.test.client.Client] -> servetr port:10000
INFO[13-10-10 10:04:23][com.test.client.Client] -> Client socket establish success!
INFO[13-10-10 10:04:23][com.test.client.Client] -> server answer:server

Server端日志:

INFO[13-10-10 10:04:19][com.test.server.Server] -> Server start up!
INFO[13-10-10 10:04:23][com.test.server.Server] -> client request:your name?

PS:

这里要特别说明一下DataInputStream这个类的readShort方法:

public final short readShort() throws IOException {
int ch1 = in.read();
int ch2 = in.read();
if ((ch1 | ch2) < 0)
throw new EOFException();
return (short)((ch1 << 8) + (ch2 << 0));
}

可以看到是先读高位,再读低位

再来看下DataOutputStream这个类的writeShort方法:

public final void writeShort(int v) throws IOException {
out.write((v >>> 8) & 0xFF);
out.write((v >>> 0) & 0xFF);
incCount(2);
}

可以看到是先写高位,再写低位

如果传输Short类型数据(其它类型数据相同)时,要求先传低位,再传高位,则不能使用自带的方法

将数据转为低位在前高位在后的字节数组,然后传输整个数组即可

public void write(byte b[]) throws IOException {
write(b, 0, b.length);
}
public void write(byte b[], int off, int len) throws IOException {
if ((off | len | (b.length - (len + off)) | (off + len)) < 0)
throw new IndexOutOfBoundsException(); for (int i = 0 ; i < len ; i++) {
write(b[off + i]);
}
}

Java Socket简例的更多相关文章

  1. Java socket中关闭IO流后,发生什么事?(以关闭输出流为例)

    声明:该博文以socket中,关闭输出流为例进行说明. 为了方便讲解,我们把DataOutputstream dout = new DataOutputStream(new BufferedOutpu ...

  2. linux下C语言socket网络编程简例

    原创文章,转载请注明转载字样和出处,谢谢! 这里给出在linux下的简单socket网络编程的实例,使用tcp协议进行通信,服务端进行监听,在收到client的连接后,发送数据给client:clie ...

  3. 5.3linux下C语言socket网络编程简例

    原创文章,转载请注明转载字样和出处,谢谢! 这里给出在Linux下的简单socket网络编程的实例,使用tcp协议进行通信,服务端进行监听,在收到客户端的连接后,发送数据给客户端:客户端在接受到数据后 ...

  4. 深入学习socket网络编程,以java语言为例

    了解java的socket编程与Linux Socket API之间的关系 一.java的网络编程 1.socket原理 socket通信就是通过IP和端口号将两台主机建立连接,提供通信.主机A的应用 ...

  5. Java Socket Server的演进 (一)

    最近在看一些网络服务器的设计, 本文就从起源的角度介绍一下现代网络服务器处理并发连接的思路, 例子就用java提供的API. 1.单线程同步阻塞式服务器及操作系统API 此种是最简单的socket服务 ...

  6. 《程序设计教学法--以Java程序设计为例》

    <程序设计教学法--以Java程序设计为例> 当老师上的第一门课就是<Java程序设计>,工作以来,断断续续上了近十次课了吧.十几年来,教材.课程内容.教学方法.教学手段不断改 ...

  7. Java Socket编程题库

    一.    填空题 ___ IP地址____用来标志网络中的一个通信实体的地址.通信实体可以是计算机,路由器等. 统一资源定位符URL是指向互联网"资源"的指针,由4部分组成:协议 ...

  8. Java基础:三步学会Java Socket编程

    Java基础:三步学会Java Socket编程 http://tech.163.com 2006-04-10 09:17:18 来源: java-cn 网友评论11 条 论坛        第一步 ...

  9. 如何为可扩展系统进行Java Socket编程

    从简单I/O到异步非阻塞channel的Java Socket模型演变之旅 上世纪九十年代后期,我在一家在线视频游戏工资工作,在哪里我主要的工作就是编写Unix Unix Berkley Socket ...

随机推荐

  1. URAL1036. Lucky Tickets

    链接 dp[i][j] += dp[i-1][j-g];背包吧 数据太大了 还是JAVA好用 import java.io.*; import java.math.*; import java.tex ...

  2. 【转】NI语法 JNI参考 JNI函数大全

    原文网址:http://blog.sina.com.cn/s/blog_5de73d0b0101chk1.html 一.对照表 Java类型    本地类型         描述boolean     ...

  3. SharePoint 2010 master page 控件介绍(2):ribbon (一同事读听着像泪奔)

    转:http://blog.csdn.net/lgm97/article/details/6409208 <!-- =====  开始Ribbon ======================= ...

  4. VC一些经验系列: 《分享泄漏检测工具:内存、DC、GDI、Handle... 》

    分享下自己工作中用到的一些用于泄漏检测的工具 后面的是DC的一些定义和注意事项.(不喜勿看) //=================================================== ...

  5. Windows下Lua+Redis 断点调试环境搭建==Linux下类似

    Lua+Redis 断点调试环境搭建 windows环境,使用Redis,写lua脚本头疼的问题之一不能对脚本断点调试,google加上自己的摸索,终于搞定. 1.下载ZeroBraneStudio, ...

  6. dev/null和dev/zero区别 以及换回设备(loopback device)

    转自:http://blog.chinaunix.net/uid-20729677-id-765105.html dev/zero,是一个输入设备,你可你用它来初始化文件. /dev/zero---- ...

  7. 除去重复记录distinct

    在查询数据库时候,可以使用distinct关键字过滤重复记录 例如 SELECT distinct ShiftID FROM [AdventureWorks].[HumanResources].[Em ...

  8. Spark在集群中的安装

    今天由于所以要安装spark做一些实验.我已有的环境是: 操作系统:CentOS6.5 hadoop:hadoop2.4.1 JDK:1.7 集群环境:四个节点   闲话不说,以下是我的安装步骤: 说 ...

  9. HW5.20

    public class Solution { public static void main(String[] args) { System.out.printf("%s\t%s\t%s\ ...

  10. CentOS下源码安装Apache2.4+PHP5.4+MySQL5.5

    一.准备(把所有的源文件放在‘/home/yuanjun’目录下) apr http://mirror.bjtu.edu.cn/apache/apr/apr-1.4.6.tar.gz apr-util ...