1.TCP协议
(1)面向连接:两个远程主机(或者叫进程,因为实际上远程通信是进程之间的通信,而进程则是运行中的 程序),必须首先进行一个握手过程,确认连接成功,之后才能传输实际的数据。
(2)全双工:两个主机上的进程(比如进程A、进程B),一旦建立好连接,那么数据就既可以由A流向B,也可以由B流向A。
(3)点对点:一个TCP连接总是两者之间的,在发送中,通过一个连接将数据发给多个接收方是不可能的。
(4)可靠的数据传输:连接建立后,数据的发送一定能够到达,并且是有序的。
2.服务器对客户端的服务能力:
(1)处理同一客户端的一个请求。
(2)处理同一客户端的多个请求。
(3)处理多个客户端的一个请求。
(4)处理多个客户端的多个请求。
3.数据传输的方式
(1)流数据(TCP)
(2)数据报(UDP)
4.数据的接收与发送方式:
(1)同步传输
(2)异步传输
5.所用到的类
(1)Socket 位于:System.Net.Sockets
(2)TcpListener , TcpClient :位于System.Net.Sockets。这两个类是对Socket 的包装。
(3)IPAddress ,IPEndPoint。位于:System.Net。
6.实例:
客户端发送一个字符串给服务器,服务器将小写改为大写,回发给客户端。
服务器:
using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;
class Server
{
private IPAddress ip; //IP地址
private TcpListener Listener;
private int point; //端口
public Server(String StrIP,int Point)
{
ip = IPAddress.Parse(StrIP); //设置IP地址
point = Point; //设置端口
Listener = new TcpListener(ip, Point); //创建监听
Console.WriteLine("Server is running");
Listener.Start(); //开启监听
Console.WriteLine("Server is listening");
}
static void Main(String[] args)
{
Server server = new Server("127.0.0.1", 8250);
TcpClient RemoteClient = server.Listener.AcceptTcpClient(); //获取一个连接
server.AcceptHandler(RemoteClient); //对客户连接的处理
server.blocked(); //直到按Q退出程序
}
//用于处理一个连接
private void AcceptHandler(TcpClient RemoteClient)
{
Console.WriteLine("Client is Connected {0}-->{1}", RemoteClient.Client.LocalEndPoint,
RemoteClient.Client.RemoteEndPoint);
NetworkStream StreamToClient = RemoteClient.GetStream(); //获取网络的数据流
String msg = receiveMsg(StreamToClient); //接收信息
sendMsg(StreamToClient, msg); //向网络回发信息
}
//用于接收信息的函数
private String receiveMsg(NetworkStream StreamToClient)
{
byte[] buffer = new byte[1024]; //用于接收的缓冲区
int bytes = StreamToClient.Read(buffer, 0, buffer.Length); //从网络中读取信息
Console.WriteLine("Reading data : {0} bytes", bytes);
String msg = Encoding.Unicode.GetString(buffer, 0, bytes); //将收到的信息解码成字符串
Console.WriteLine("From Client Receive: {0}", msg); //输出
return msg;
}
//用于回发信息的函数
private void sendMsg(NetworkStream StreamToClient,String msg)
{
String SendMsg = msg.ToUpper(); //将收到的信息小写改为大写
byte[] temp = Encoding.Unicode.GetBytes(SendMsg); //进行编码
StreamToClient.Write(temp, 0, temp.Length); //回发给客户端
}
//此方法用于阻塞程序
private void blocked()
{
Console.WriteLine("/n/n输入/"Q/"键退出。");
ConsoleKey key;
do
{
key = Console.ReadKey(true).Key;
} while (key != ConsoleKey.Q);
}
}
客户端:
using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;
class Client
{
private IPAddress ip;//IP地址
private int point;//端口
private TcpClient client;
public Client(String ipStr, int Point)
{
ip = IPAddress.Parse(ipStr);
point = Point;
client = new TcpClient();
Console.WriteLine("Client is running");
client.Connect(ip, point); //连接到服务器
Console.WriteLine("Server is Connected : {0}-->{1}", client.Client.LocalEndPoint,
client.Client.RemoteEndPoint);
}
static void Main(String[] args)
{
Client C = new Client("127.0.0.1", 8250);
NetworkStream StreamToServer = C.client.GetStream(); //获取用于网络的数据流
String msg = "Welcome to China";
C.sendMsg(StreamToServer, msg); //发送信息
C.receiveMsg(StreamToServer); //接收信息
C.blocked();
}
//发送信息
private void sendMsg(NetworkStream StreamToServer,String msg)
{
byte[] temp = Encoding.Unicode.GetBytes(msg); //对字符串进行编码
StreamToServer.Write(temp, 0, temp.Length); //将缓冲区的数据写入网络
Console.WriteLine("Send-->: {0}", msg); //显示发送的信息
}
//接收信息
private void receiveMsg(NetworkStream StreamToServer)
{
byte[] buffer = new byte[1024];
int bytes = StreamToServer.Read(buffer, 0, buffer.Length); //从网络中读取固定字节的数据
String ReceiveMsg = Encoding.Unicode.GetString(buffer, 0, bytes);
Console.WriteLine("From Server: {0}", ReceiveMsg); //显示接收到的字符串
}
/// <summary>
/// 用于阻塞程序的方法
/// </summary>
private void blocked()
{
Console.WriteLine("/n/n输入/"Q/"键退出。");
ConsoleKey key;
do
{
key = Console.ReadKey(true).Key;
} while (key != ConsoleKey.Q);
}
}
本例子是利用同步方法实现,也就是说当客户端没去连接服务器时,服务器仅能处于等待连接,且只能处理一个客户的一个请求。
如果要处理同一客户的多个请求只需:在接收和发送加上while语句。
服务器:
private void AcceptHandler(TcpClient RemoteClient)
{
Console.WriteLine("Client is Connected {0}-->{1}", RemoteClient.Client.LocalEndPoint,
RemoteClient.Client.RemoteEndPoint);
NetworkStream StreamToClient = RemoteClient.GetStream(); //获取网络的数据流
do
{
String msg = receiveMsg(StreamToClient); //接收信息
sendMsg(StreamToClient, msg); //向网络回发信息
}
while (true);
}
客户端:
static void Main(String[] args)
{
Client C = new Client("127.0.0.1", 8250);
NetworkStream StreamToServer = C.client.GetStream(); //获取用于网络的数据流
String msg = "Welcome to China";
do
{
msg = Console.ReadLine();
C.sendMsg(StreamToServer, msg); //发送信息
C.receiveMsg(StreamToServer); //接收信息
}
while (true);
}
同理只要再加上while语句,及改变位置,便可实现:
(2)处理同一客户端的多个请求。
(3)处理多个客户端的一个请求。
(4)处理多个客户端的多个请求。