网络编程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 ...
随机推荐
- Visual C++ 8.0对象布局的奥秘:虚函数、多继承、虚拟继承(VC直接输出内存布局)
原文:VC8_Object_Layout_Secret.html 哈哈,从M$ Visual C++ Team的Andy Rich那里又偷学到一招:VC8的隐含编译项/d1reportSingleCl ...
- 关于javascript document.createDocumentFragment() 替代insertCell、insertRow这种每次都使用大量的资源导致浏览器崩溃
documentFragment 是一個無父對象的document對象他支持以下DOM2方法: appendChild, cloneNode, hasAttributes, hasChildNodes ...
- 【HDOJ】3345 War Chess
简单BFS.注意最后一组数据,每个初始点不考虑周围是否有敌人. /* 3345 */ #include <iostream> #include <cstdio> #includ ...
- 数据结构(Splay平衡树): [NOI2007] 项链工厂
[NOI2007] 项链工厂 ★★★ 输入文件:necklace.in 输出文件:necklace.out 简单对比 时间限制:4 s 内存限制:512 MB [问题描述] T公司是一 ...
- HDOJ 2073 无限的路
Problem Description 甜甜从小就喜欢画图画,最近他买了一支智能画笔,由于刚刚接触,所以甜甜只会用它来画直线,于是他就在平面直角坐标系中画出如下的图形: 甜甜的好朋友蜜蜜发现上面的图还 ...
- [LeetCode] 141&142 Linked List Cycle I & II
Problem: Given a linked list, determine if it has a cycle in it. Follow up:Can you solve it without ...
- SQL 第二章 作业
/*第二章 作业*/ create table S ( sno char(2) NOT NULL UNIQUE, sname char(3), city char(2) ); alter table ...
- VGO新闻 - VGO
VGO新闻 - VGO VGO天津伊势丹店盛装揭幕 VGO天津伊势丹店盛装揭幕2013年9月7日,VGO(微高)全国首家实体店在天津伊势丹百货盛装开幕.现场,100多位商场领导及业内同仁共同出席了
- poj1017
一个工厂制造的产品形状都是长方体,它们的高度都是h,长和宽都相等,一共有六个型号,他们的长宽分别为1*1, 2*2, 3*3, 4*4, 5*5, 6*6.这些产品通常使用一个 6*6*h 的长方体包 ...
- 浅谈异步IO各模型优缺点
本文只讨论OverLapped I/O的三种异步模型及完成端口,像select.SWASelect不作讨论,讨论顺序从劣到优,方便于循序渐进地对比,更容易区分各模型之间的差别. 1. OverLapp ...