陈振辉虞在洋网络编程聊天程序报告.docx
《陈振辉虞在洋网络编程聊天程序报告.docx》由会员分享,可在线阅读,更多相关《陈振辉虞在洋网络编程聊天程序报告.docx(17页珍藏版)》请在冰豆网上搜索。
陈振辉虞在洋网络编程聊天程序报告
网络编程实验报告
-----C#语言编写聊天程序
Winform平台
学号12224506
姓名:
陈振辉
姓名:
虞在洋
专业:
:
计算机科学与技术
班级:
5班
一、实验目的:
(1)熟悉和掌握网络编程的基本方法和步骤;
(2)进一步理解client/server交互模式;
(3)加深学生对于网络协议概念的理解以及协议的设计和实现方法。
二、实验任务:
使用任意网络编程语言(Java、C、VB、Delphi等)编写网络选课模拟程序,它由client和server两部分组成,client和server之间的通信基于TCP协议。
实现数据的收发。
三、网络编程:
大多数网络应用程序都遵从client/server交互模型。
该模型中,服务器应用是一种专门用来提供某一种服务的程序,它被动地等待通信,而客户应用主动地启动通信,请求服务器的服务。
服务器程序既可以接收信息也能发送信息,还可以成为客户。
TCP/UDP赋予每个服务一个唯一的协议端口号。
服务器程序通过协议端口号来指定它所提供的服务,然后被动地等待通信。
客户在发送连接请求时,必须说明服务器程序运行主机的IP地址和协议端口号来指定它所希望的服务。
服务器端计算机通过此端口号将收到的请求转向正确的服务器程序。
大多数网络编程语言都提供或者使用控件封装了套接字应用程序接口(SocketAPI),应用程序通过套接字接口调用来实现和传输层交互。
用户目前可以使用两种套接口,即流套接字TCP和数据报套接字UDP。
流式套接字定义了一种可靠的面向连接的服务,提供了双向的,有序的,无重复并且无记录边界的数据流服务。
数据报套接字定义了一种无连接的服务,支持双向的数据流,但并不保证是可靠,有序,无重复的。
也就是说,一个从数据报套接字接收信息的进程有可能发现信息重复了,或者和发出时的顺序不同。
数据报套接字的一个重要特点是它保留了记录边界。
套节字API主要包括表1所示的接口。
使用面向连接的套接字编程,通过图2来表示其时序。
套接字工作过程如下:
服务器首先启动,通过调用socket()建立一个套接字,然后调用bind()将该套接字和本地网络地址联系在一起,再调用listen()使套接字做好侦听的准备,并规定它的请求队列的长度,之后就调用accept()来接收连接。
客户在建立套接字后就可调用connect()和服务器建立连接,连接一旦建立,客户机和服务器之间就可以通过调用read()和write()来发送和接收数据。
最后,待数据传送结束后,双方调用close()关闭套接字。
表1套节字API主要接口
接口
解释
SOCKET
BIND
LISTEN
ACCEPT
CONNET
SEND
RECV
CLOSE
创建一个新的套接字
给服务器绑定一个传输层地址
将服务器设为被动模式
接收客户的一个请求
客户向服务器发起连接
向一个连接的套接字发送数据
从一个连接的套接字接收数据
终止一个连接
四.程序设计及编程思路
打开Vc2010新建一个winform工程文件
如图客户端
usingSystem;
usingSystem.Collections.Generic;
usingSystem.ComponentModel;
usingSystem.Data;
usingSystem.Drawing;
usingSystem.Linq;
usingSystem.Text;
usingSystem.Windows.Forms;
usingSystem.Net.Sockets;
usingSystem.Threading;
usingSystem.Net;
usingSystem.IO;
usingSystem.IO;
namespaceChatClient
{
publicpartialclassFClient:
Form
{
publicFClient()
{
InitializeComponent();
//关闭对文本框的非法线程操作检查
TextBox.CheckForIllegalCrossThreadCalls=false;
}
//创建1个客户端套接字和1个负责监听服务端请求的线程
SocketsocketClient=null;
ThreadthreadClient=null;
privatevoidbtnBeginListen_Click(objectsender,EventArgse)
{
//定义一个套字节监听包含3个参数(IP4寻址协议,流式连接,TCP协议)
socketClient=newSocket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
//需要获取文本框中的IP地址
IPAddressipaddress=IPAddress.Parse(txtIP.Text.Trim());
//将获取的ip地址和端口号绑定到网络节点endpoint上
IPEndPointendpoint=newIPEndPoint(ipaddress,int.Parse(txtPort.Text.Trim()));
//这里客户端套接字连接到网络节点(服务端)用的方法是Connect而不是Bind
socketClient.Connect(endpoint);
//创建一个线程用于监听服务端发来的消息
threadClient=newThread(RecMsg);
//将窗体线程设置为与后台同步
threadClient.IsBackground=true;
//启动线程
threadClient.Start();
button1.Enabled=false;
//MessageBox.Show("连接成功!
");
txtMsg.Text=niechen.Text+"连接服务器成功"+"\n";
btnBeginListen.Enabled=false;
}
///接收服务端发来信息的方法
///
privatevoidRecMsg()
{
while(true)//持续监听服务端发来的消息
{
//定义一个1M的内存缓冲区用于临时性存储接收到的信息
byte[]arrRecMsg=newbyte[1024*1024];
//将客户端套接字接收到的数据存入内存缓冲区,并获取其长度
intlength=socketClient.Receive(arrRecMsg);
//将套接字获取到的字节数组转换为人可以看懂的字符串
stringstrRecMsg=Encoding.UTF8.GetString(arrRecMsg,0,length);
//将发送的信息追加到聊天内容文本框中
//txtMsg.AppendText("服务器:
"+GetCurrentTime()+"\r\n"+strRecMsg+"\r\n");
txtMsg.AppendText(strRecMsg);
}
}
///发送字符串信息到服务端的方法
///
///发送的字符串信息
privatevoidClientSendMsg(stringsendMsg)
{
//将输入的内容字符串转换为机器可以识别的字节数组
byte[]arrClientSendMsg=Encoding.UTF8.GetBytes(sendMsg);
//调用客户端套接字发送字节数组
socketClient.Send(arrClientSendMsg);
//将发送的信息追加到聊天内容文本框中
//txtMsg.AppendText(niechen.Text+GetCurrentTime()+"\r\n"+sendMsg+"\r\n");
}
privatevoidbtnSend_Click(objectsender,EventArgse)
{
if(niechen.Text=="")niechen.Text="游客";
//调用ClientSendMsg方法将文本框中输入的信息发送给服务端
ClientSendMsg(niechen.Text+GetCurrentTime()+"\r\n"+txtCMsg.Text.Trim()+"\r\n");
txtCMsg.Text="";
txtCMsg.Focus();
}
//快捷键Enter发送信息
privatevoidtxtCMsg_KeyDown(objectsender,KeyEventArgse)
{
//当光标位于文本框时如果用户按下了键盘上的Enter键
if(e.KeyCode==Keys.Enter)
{
//则调用客户端向服务端发送信息的方法
ClientSendMsg(txtCMsg.Text.Trim());
}
}
///获取当前系统时间的方法
///
///当前时间
privateDateTimeGetCurrentTime()
{
DateTimecurrentTime=newDateTime();
currentTime=DateTime.Now;
returncurrentTime;
}
privatevoidbutton1_Click(objectsender,EventArgse)
{
this.Hide();
FServerf=newFServer();
f.ShowDialog();
}
//发送文件
/*stringstrFile="";
boolisFile=false;
boolready=false;
TcpClientclient=newTcpClient("txtIP.Text",8000);
//TcpListenerlistener=newTcpListener(8000);
//Sockets=listener.AcceptSocket();
staticInt32port=13000;
staticIPAddresslocalAddr=IPAddress.Parse("127.0.0.1");
staticTcpListenertcpListener=newTcpListener(localAddr,port);
Sockets=tcpListener.AcceptSocket();
privatevoidSendFile()
{
if(strFile!
="")//strFile是全局变量,用于保存发送发的文件路径
{
//发送传送文件请求
isFile=true;//is