服务端:

1. 创建 ServerSocket 对象并监听一个端口

2. 调用accept()方法等待客户端的连接(阻塞式)

3. 输入流(记取客户端发送过来的数据)

4. 输出流(响应客户端请求,即向客户端发送数据)

5. 关闭资源

package cn.jmu.edu;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket; /**
* 基于TCP 协议的Socket 通信,实现用户登陆
* 服务器端
*
* @author Sky
* @date 2016年10月27日
*/
public class Server {
public static void main(String[] args) {
try {
//1.创建一个服务端Socket,即ServerSocket,指定端口并监听此端口
ServerSocket serverSocket = new ServerSocket(8888);
System.out.println("***服务器即将启动,等待客户端的连接***");
//2.调用accept方法开始监听,等待客户端的连接
Socket socket = serverSocket.accept(); //3.获取输入流,并读取用户信息
InputStream is = socket.getInputStream(); //获取字节流入流
InputStreamReader isr = new InputStreamReader(is); //将字节输入流转化为字符输入流
BufferedReader br = new BufferedReader(isr); //为字符输入流添加缓冲
String info = null;
while((info=br.readLine()) != null){ //循环读取客户端发送的信息
System.out.println("我是服务器,客户端说:" + info);
}
socket.shutdownInput(); //关闭输入流 //4.获取输出流,响应客户端的请求
OutputStream os = socket.getOutputStream();
PrintWriter pw = new PrintWriter(os); //打包为打印流
pw.write("欢迎您!");
pw.flush(); //刷新缓冲区的数据,将数据输出 //5.关闭资源
pw.close();
os.close();
br.close();
isr.close();
is.close();
socket.close();
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

客户端:

1. 创建 Socket 对象,传入服务器端的 IP 和监听的端口参数

2. 输出流(给服务器端发送数据)

3. 输入流(接收服务器端返回的信息)

4. 关闭资源

package cn.jmu.edu;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket; /**
* 客户端
*
* @author Sky
* @date 2016年10月27日
*/
public class Client {
public static void main(String[] args) {
try {
//1.创建客户端Socket,指定服务器地址和端口
Socket socket = new Socket("localhost", 8888);
//2.获取输出流,向服务器端发送信息
OutputStream os = socket.getOutputStream(); //字节输出流
PrintWriter pw = new PrintWriter(os); //将输出流打包为打印流
pw.write("用户名:Sky;密码:winner");
pw.flush(); //刷新数据,向服务器发送数据
socket.shutdownOutput(); //关闭输出流 //3.获取输入流,并读取服务器端的响应信息
InputStream is = socket.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String info = null;
while((info=br.readLine()) != null){
System.out.println("我是客户端,服务端回答:" + info);
} //4.关闭资源
br.close();
is.close();
pw.close();
os.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

上面是最基础的TCP通信编程,只能一个客户端连接一个服务器。下面改造成使用多线程实现多客户端的通信,一个服务器端有多个客户端连接。

服务端类 Server.java

package cn.jmu.edu;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket; /**
* 基于TCP 协议的Socket 通信,实现用户登陆
* 服务器端
*
* @author Sky
* @date 2016年10月27日
*/
public class Server {
public static void main(String[] args) {
try {
Socket socket = null;
int count = 0; //记录客户端数量
//1.创建一个服务端Socket,即ServerSocket,指定端口并监听此端口
ServerSocket serverSocket = new ServerSocket(8888);
System.out.println("***服务器即将启动,等待客户端的连接***");
//循环监听等待客户端的连接
while(true){
//调用accept方法开始监听,等待客户端的连接
socket = serverSocket.accept();
//创建一个新的线程
ServerThread serverThread = new ServerThread(socket);
//启动线程
serverThread.start(); count++; //统计客户端的数量
System.out.println("客户端数量:" + count);
//使用 InetAddress 对象获取客户端主机的IP地址
InetAddress address = socket.getInetAddress();
System.out.println("当前客户端的IP地址:" + address.getHostAddress());
}
} catch (IOException e) {
e.printStackTrace();
}
}
}

服务端多线程类 ServerThread.java

package cn.jmu.edu;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket; /**
* 服务器端线程处理类
*
* @author Sky
* @date 2016年10月28日
*/
public class ServerThread extends Thread {
//和本线程相关的Socket
Socket socket = null;
//构造方法对socket进行初始化
public ServerThread(Socket socket){
this.socket = socket;
} //执行线程的操作,响应客户端请求
@Override
public void run() {
InputStream is = null;
InputStreamReader isr = null;
BufferedReader br = null;
OutputStream os = null;
PrintWriter pw = null;
try {
//3.获取输入流,并读取用户信息
is = socket.getInputStream(); //获取字节流入流
isr = new InputStreamReader(is); //将字节输入流转化为字符输入流
br = new BufferedReader(isr); //为字符输入流添加缓冲 String info = null;
while((info=br.readLine()) != null){ //循环读取客户端发送的信息
System.out.println("我是服务器,客户端说:" + info);
}
socket.shutdownInput(); //关闭输入流 //4.获取输出流,响应客户端的请求
os = socket.getOutputStream();
pw = new PrintWriter(os); //打包为打印流
pw.write("欢迎您!");
pw.flush(); //刷新缓冲区的数据,将数据输出 } catch (IOException e) {
e.printStackTrace();
} finally {
//5.关闭资源
try {
if (pw != null)
pw.close();
if (os != null)
os.close();
if (br != null)
br.close();
if (isr != null)
isr.close();
if (is != null)
is.close();
if (socket != null)
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
super.run();
}
}

客户端类不变。

运行效果:

网络编程Socket之TCP的更多相关文章

  1. 网络编程Socket之TCP之close/shutdown具体解释(续)

    接着上一篇网络编程Socket之TCP之close/shutdown具体解释 如今我们看看对于不同情况的close的返回情况和可能遇到的一些问题: 1.默认操作的close 说明:我们已经知道writ ...

  2. java网络编程socket\server\TCP笔记(转)

    java网络编程socket\server\TCP笔记(转) 2012-12-14 08:30:04|  分类: Socket |  标签:java  |举报|字号 订阅     1 TCP的开销 a ...

  3. python网络编程(Socket、TCP、UDP)

    Socket 是网络编程的一个抽象概念,通常我们用一个Socket表示 "打开了一个网络链接",而打开一个Socket 需要知道目标计算机的IP 地址和端口号,再指定协议类型即可. ...

  4. IPv6下网络编程socket, TCP和UDP例子,以及兼容IPV4和IPV6的类

    一.TCP socket ipv6与ipv4的区别 服务器端源代码如下: #include <stdio.h> #include <stdlib.h> #include < ...

  5. 网络编程Socket它TCP它TIME_WAIT国家具体解释

    下面我们用最简单的一对一的客户server编程模型重现遇到的一些问题: 初学者socket当写作socket名其妙的问题.比方说bind函数返回的常见错误是EADDRINUSE 使用以下的程序重现这个 ...

  6. 二、网络编程-socket之TCP协议开发客户端和服务端通信

    知识点:之前讲的udp协议传输数据是不安全的,不可靠不稳定的,tcp协议传输数据安全可靠,因为它们的通讯机制是不一样的.udp是用户数据报传输,也就是直接丢一个数据包给另外一个程序,就好比寄信给别人, ...

  7. 网络编程Socket之TCP之connect具体解释

    对TCP套接字调用connect会激发三次握手,例如以下: client是主动打开连接的一端,会发送第一个SYN分节,然后等待确认,此时连接状态为SYN_SENT,当收到服务端的确认后连接建立,状态变 ...

  8. python_网络编程socket(TCP)

    服务端: import socket sk = socket.socket() #创建对象 sk.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) ...

  9. Python网络编程02 /基于TCP、UDP协议的socket简单的通信、字符串转bytes类型

    Python网络编程02 /基于TCP.UDP协议的socket简单的通信.字符串转bytes类型 目录 Python网络编程02 /基于TCP.UDP协议的socket简单的通信.字符串转bytes ...

随机推荐

  1. Request.url用法

    原文:Request.url用法 我們在開發網頁應用程式,時常需要去解析網址(Request.Url)的每個片段,進行一些判斷.例如說 "http://localhost:1897/News ...

  2. 用 SQL 脚本读取Excel 中的sheet数量及名称

    -- Get table (worksheet) or column (field) listings from an excel spreadsheet -- 设置变量 declare @linke ...

  3. fdisk磁盘分区

    http://www.cr173.com/html/4336_1.html http://www.51cto.com/art/200602/20328.htm

  4. phpMyAdmin 完整路径泄露漏洞

    漏洞名称: phpMyAdmin 完整路径泄露漏洞 CNNVD编号: CNNVD-201307-650 发布时间: 2013-08-09 更新时间: 2013-08-09 危害等级: 中危   漏洞类 ...

  5. 图论(网络流):COGS 410. [NOI2009] 植物大战僵尸

    410. [NOI2009] 植物大战僵尸 ★★★   输入文件:pvz.in   输出文件:pvz.out   简单对比时间限制:2 s   内存限制:512 MB [问题描述] Plants vs ...

  6. 后缀自动机(SAM) :SPOJ LCS - Longest Common Substring

    LCS - Longest Common Substring no tags  A string is finite sequence of characters over a non-empty f ...

  7. 关于aspx 页面生成html 源码顶部空行不得不说的事儿

    原文引用自 http://www.360doc.com/content/12/0910/21/10504424_235418578.shtml 使用.aspx生成的页面一般都会有一个或多个空行,当然这 ...

  8. bzoj 2330 [SCOI2011]糖果(差分约束系统)

    2330: [SCOI2011]糖果 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 3574  Solved: 1077[Submit][Status ...

  9. SRM 395(1-250pt)

    DIV1 250pt 题意:在平面直角坐标系中,只能走到整点,每次有两种移动方法,可以沿平行于坐标轴方向走,也可以沿45度方向走,前者走一步耗时wt,后者走一步耗时st.比如从(x, y)可以走到(x ...

  10. Failed to execute goal org.apache.maven.plugins:maven-clean-plugin:2.5:clean (default-clean) on project taotao-manager-web: Failed to clean project: Failed to delete \target\tomcat\logs\access_log.201

    点击console右上角叉号然后再点击红色小方形terminate