网络编程Socket之TCP

服务端:
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的更多相关文章
- 网络编程Socket之TCP之close/shutdown具体解释(续)
接着上一篇网络编程Socket之TCP之close/shutdown具体解释 如今我们看看对于不同情况的close的返回情况和可能遇到的一些问题: 1.默认操作的close 说明:我们已经知道writ ...
- java网络编程socket\server\TCP笔记(转)
java网络编程socket\server\TCP笔记(转) 2012-12-14 08:30:04| 分类: Socket | 标签:java |举报|字号 订阅 1 TCP的开销 a ...
- python网络编程(Socket、TCP、UDP)
Socket 是网络编程的一个抽象概念,通常我们用一个Socket表示 "打开了一个网络链接",而打开一个Socket 需要知道目标计算机的IP 地址和端口号,再指定协议类型即可. ...
- IPv6下网络编程socket, TCP和UDP例子,以及兼容IPV4和IPV6的类
一.TCP socket ipv6与ipv4的区别 服务器端源代码如下: #include <stdio.h> #include <stdlib.h> #include < ...
- 网络编程Socket它TCP它TIME_WAIT国家具体解释
下面我们用最简单的一对一的客户server编程模型重现遇到的一些问题: 初学者socket当写作socket名其妙的问题.比方说bind函数返回的常见错误是EADDRINUSE 使用以下的程序重现这个 ...
- 二、网络编程-socket之TCP协议开发客户端和服务端通信
知识点:之前讲的udp协议传输数据是不安全的,不可靠不稳定的,tcp协议传输数据安全可靠,因为它们的通讯机制是不一样的.udp是用户数据报传输,也就是直接丢一个数据包给另外一个程序,就好比寄信给别人, ...
- 网络编程Socket之TCP之connect具体解释
对TCP套接字调用connect会激发三次握手,例如以下: client是主动打开连接的一端,会发送第一个SYN分节,然后等待确认,此时连接状态为SYN_SENT,当收到服务端的确认后连接建立,状态变 ...
- python_网络编程socket(TCP)
服务端: import socket sk = socket.socket() #创建对象 sk.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) ...
- Python网络编程02 /基于TCP、UDP协议的socket简单的通信、字符串转bytes类型
Python网络编程02 /基于TCP.UDP协议的socket简单的通信.字符串转bytes类型 目录 Python网络编程02 /基于TCP.UDP协议的socket简单的通信.字符串转bytes ...
随机推荐
- 从相对路径说开来(从C++到Qt)
从相对路径说开来(从C++到Qt) 转载自:http://blog.csdn.net/dbzhang800/article/details/6363165 在Qt论坛经常看到网友抱怨: QPixmap ...
- [置顶] 技术人血泪史:七种IT失误让你直接走人
IT人士的真实故事:搞出大麻烦,旋即遭解雇 如今想找一份理想的IT工作并不容易,但丢掉一份工作却非常简单. 导致自己被炒鱿鱼的原因很多,无论是没能尽到保护雇主数字资产的义务.或者是滥用手中的权限以达到 ...
- bzoj3531
不难想到树链剖分这题的难点是记录的是路径上宗教相同的点裸的想法是对每一种宗教都开一棵线段树,记录每个点的评级但显然这样会爆空间,仔细分析一下,这些线段树内很多点压根就没用到因此我们考虑对线段树动态开点 ...
- POJ-Common Substrings(后缀数组-长度不小于 k 的公共子串的个数)
题意: 长度不小于 k 的公共子串的个数 分析: 基本思路是计算 A 的所有后缀和 B 的所有后缀之间的最长公共前缀的长度,把最长公共前缀长度不小于 k 的部分全部加起来. 先将两个字符串连起来,中间 ...
- Javascript面向对象编程(三):非构造函数的继承 by 阮一峰
今天是最后一个部分,介绍不使用构造函数实现"继承". 一.什么是"非构造函数"的继承? 比如,现在有一个对象,叫做"中国人". var Ch ...
- 去掉cell边框的简单办法
实很简单,把backgroundView设置为一个空的View,然后就干净了 UIView *tempView = [[UIView alloc] init]; [cell setBackground ...
- Fragmen横竖屏切换,导致页面混乱,oncreateView重复调用
在清单文件Activity设置属性 android:screenOrientation="landscape" android:configChanges="screen ...
- Java里的IO流里的FileInputStream 的读取并在前打印行数!
大家好!!新人求罩! import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException ...
- JVM调优之jstack找出发生死锁的线程
1.执行死锁程序 2.执行 jstack -l 21733 | more 结果如下: 死锁程序: public static void main(String[] args) { // TODO Au ...
- Android源码学习
http://android-wheel.googlecode.com/svn/trunk/android-wheel-read-only 在github上面有一个叫做 android-wheel 的 ...