C++网络编程(socket)我要写一个服务器端程序和一个客户端程序

C++网络编程(socket)我要写一个服务器端程序和一个客户端程序,第1张

呵呵,当让可以了。

1、首先我说一下他们的关系:

一个解决方案(sln)中可以包含多个项目(vcxproj);

这些项目可以是互不相关的,也可以是相关的;

2、下面说如何将你的两个项目放在同一个解决方案里

你将一个的项目(B)拷贝到另外一个项目中(A)(其中文件夹A和B中含有vcxproj);

你有Avcxproj和Bvcxproj两个项目,他们分别为

文件夹A(其中含有Avcxproj) 和 文件夹B(其中含有Bvcxproj)

解决方案(Csln)和文件夹A和B在同一目录下。

然后打开对应的解决方案,添加项目,将刚才的B项目添加即可;

3、设置启动项目。

今天太晚了,改天给你做一个,记得提醒我,这个如果只是要个简单的,我半个小时就搞定了

给我个邮箱

现在给贴出我的代码: 整个结构分两个工程

1。服务端工程NioServerjava: 采用nio 方式的异步socket通信,不仅可以实现你的服务器还可以让你多学习一下什么是nio

2。客户端工程UserClientjava: 采用Swing技术画了一个简单的UI界面,比较土,原因是我没那么多时间去设计界面,你需要的话可以自己去修改得漂亮点,相信不难

现在贴工程1:

package comnet;

import javaioIOException;

import javanetInetSocketAddress;

import javanetServerSocket;

import javanioByteBuffer;

import javaniochannelsSelectionKey;

import javaniochannelsSelector;

import javaniochannelsServerSocketChannel;

import javaniochannelsSocketChannel;

import javautilIterator;

import javautilSet;

public class NioServer {

public static final int SERVERPORT=5555;

public static final String USERNAME="wangzhirong";

public static final String PASSWORD="123456";

public static final String ISACK="ACK";

public static final String ISNAK="NAK!";

// Selector selector;//选择器

// SelectionKey key;//key。 一个key代表一个Selector 在NIO通道上的注册,类似主键;

// //取得这个Key后就可以对Selector在通道上进行操作

private ByteBuffer echoBuffer = ByteBufferallocate( 1024 );// 通道数据缓冲区

public NioServer(){

}

public static void main(String[] args) throws IOException {

NioServer ns=new NioServer();

nsBuildNioServer();

}

public void BuildNioServer() throws IOException{

/////////////////////////////////////////////////////////

///////先对服务端的ServerSocket进行注册,注册到Selector ////

/////////////////////////////////////////////////////////

ServerSocketChannel ssc = ServerSocketChannelopen();//新建NIO通道

sscconfigureBlocking( false );//使通道为非阻塞

ServerSocket ss = sscsocket();//创建基于NIO通道的socket连接

//新建socket通道的端口

ssbind(new InetSocketAddress("127001",SERVERPORT));

Selector selector=Selectoropen();//获取一个选择器

//将NIO通道选绑定到择器,当然绑定后分配的主键为skey

SelectionKey skey = sscregister( selector, SelectionKeyOP_ACCEPT );

////////////////////////////////////////////////////////////////////

//// 接收客户端的连接Socket,并将此Socket也接连注册到Selector ////

///////////////////////////////////////////////////////////////////

while(true){

int num = selectorselect();//获取通道内是否有选择器的关心事件

if(num<1){continue; }

Set selectedKeys = selectorselectedKeys();//获取通道内关心事件的集合

Iterator it = selectedKeysiterator();

while (ithasNext()) {//遍历每个事件

try{

SelectionKey key = (SelectionKey)itnext();

//有一个新联接接入事件,服务端事件

if ((keyreadyOps() & SelectionKeyOP_ACCEPT)

== SelectionKeyOP_ACCEPT) {

// 接收这个新连接

ServerSocketChannel serverChanel = (ServerSocketChannel)keychannel();

//从serverSocketChannel中创建出与客户端的连接socketChannel

SocketChannel sc = serverChanelaccept();

scconfigureBlocking( false );

// Add the new connection to the selector

// 把新连接注册到选择器

SelectionKey newKey = scregister( selector,

SelectionKeyOP_READ );

itremove();

Systemoutprintln( "Got connection from "+sc );

}else

//读客户端数据的事件,此时有客户端发数据过来,客户端事件

if((keyreadyOps() & SelectionKeyOP_READ)

== SelectionKeyOP_READ){

// 读取数据

SocketChannel sc = (SocketChannel)keychannel();

int bytesEchoed = 0;

while((bytesEchoed = scread(echoBuffer))> 0){

Systemoutprintln("bytesEchoed:"+bytesEchoed);

}

echoBufferflip();

Systemoutprintln("limet:"+echoBufferlimit());

byte [] content = new byte[echoBufferlimit()];

echoBufferget(content);

String result=new String(content);

doPost(result,sc);

echoBufferclear();

itremove();

}

}catch(Exception e){}

}

}

}

public void doPost(String str,SocketChannel sc){

boolean isok=false;

int index=strindexOf('|');

if(index>0){

String name=strsubstring(0,index);

String pswd=strsubstring(index+1);

if(pswd==null){pswd="";}

if(name!=null){

if(nameequals(USERNAME)

&& pswdequals(PASSWORD)

){

isok=true;

}else{

isok=false;

}

}else{

isok=false;

}

}else{

isok=false;

}

String result="";

if(isok){

result="ACK";

}else{

result="NAK!";

}

ByteBuffer bb = ByteBufferallocate( resultlength() );

bbput(resultgetBytes());

bbflip();

try {

scwrite(bb);

} catch (IOException e) {

eprintStackTrace();

}

bbclear();

}

}

下面贴工程2

import javaawtColor;

import javaawtDimension;

import javaawteventActionEvent;

import javaawteventActionListener;

import javaioIOException;

import javaioInputStream;

import javaioOutputStream;

import javanetSocket;

import javanetUnknownHostException;

import javaxswingJButton;

import javaxswingJFrame;

import javaxswingJLabel;

import javaxswingJPanel;

import javaxswingJPasswordField;

import javaxswingJTextField;

public class UserClient implements ActionListener{

JFrame jf;

JPanel jp;

JLabel label_name;

JLabel label_pswd;

JTextField userName;

JButton jb;

JPasswordField paswrd;

JLabel hintStr;

public UserClient (){

jf=new JFrame("XXX 登陆系统");

jp=new JPanel();

jfsetContentPane(jp);

jfsetPreferredSize(new Dimension(350,220));

jpsetPreferredSize(new Dimension(350,220));

jpsetBackground(Colorgray);

label_name=new JLabel();

label_namesetPreferredSize(new Dimension(150,30));

label_namesetText("请输入帐户(数字或英文):");

userName=new JTextField();

userNamesetPreferredSize(new Dimension(150,30));

jpadd(label_name);

jpadd(userName);

label_pswd=new JLabel();

label_pswdsetPreferredSize(new Dimension(150,30));

label_pswdsetText("请输入密码:");

jpadd(label_pswd);

paswrd=new JPasswordField();

paswrdsetPreferredSize(new Dimension(150,30));

jpadd(paswrd);

jb=new JButton("OK");

jbsetPreferredSize(new Dimension(150,30));

jbsetText("确 定");

jbaddActionListener( this);

jpadd(jb);

hintStr=new JLabel();

hintStrsetPreferredSize(new Dimension(210,40));

hintStrsetText("");

hintStrsetForeground(ColorRED);

jpadd(hintStr);

jfpack();

jfsetVisible(true);

jfsetDefaultCloseOperation(JFrameEXIT_ON_CLOSE);

}

private String name;

private String pswd;

public void actionPerformed(ActionEvent e) {

name=userNamegetText()trim();

pswd=new String(paswrdgetPassword());

if(pswd==null){

pswd="";

}else{

pswd=pswdtrim();

}

if(name!=null && namelength()>0){

hintStrsetText("正在验证客户端,请稍候");

start();

}

}

OutputStream os;

Socket s;

InputStream is;

public void start(){

//建立联网线程

new Thread(new Runnable(){

public void run() {

try {

s=new Socket("127001",5555);

//写

os=sgetOutputStream();

oswrite(namegetBytes());

oswrite('|');//用户名与密码用"|"分隔

oswrite(pswdgetBytes());

osflush();

//读内容

Threadsleep(1000);

is=sgetInputStream();

int len=isavailable();

Systemoutprintln("len:"+len);

byte[] bytes=new byte[len];

isread(bytes);

String resut=new String(bytes);

Systemoutprintln("resut:"+resut);

//TODO 这里通过返回结果处理

if(resutequals("ACK")){

hintStrsetText("验证成功,欢迎光临!");

}else{

paswrdsetText(null);

hintStrsetText("用户名或密码错误,请重新输入");

}

} catch (UnknownHostException e) {

eprintStackTrace();

} catch (IOException e) {

eprintStackTrace();

} catch (InterruptedException e) {

eprintStackTrace();

}finally{

// try {

// osclose();

// isclose();

// sclose();

// } catch (IOException e) {

// eprintStackTrace();

// }

}

}

})start();

}

public static void main(String[] args) {

new UserClient();

}

}

下面是示例程序的简单步骤说明

服务器端:

第一步:用指定的端口号和服务器的ip建立一个EndPoint对像;

第二步:建立一个Socket对像;

第三步:用socket对像的Bind()方法绑定EndPoint;

第四步:用socket对像的Listen()方法开始监听;

第五步:接受到客户端的连接,用socket对像的Accept()方法创建新的socket对像用于和请求的客户端进行通信;

第六步:通信结束后一定记得关闭socket;

代码:

using System;

using SystemCollectionsGeneric;

using SystemText;

using SystemNet;

using SystemNetSockets;

namespace server

{

class Program

{

static void Main(string[] args)

{

int port = 2000;

string host = "127001";

/////创建终结点(EndPoint)

IPAddress ip = IPAddressParse(host);//把ip地址字符串转换为IPAddress类型的实例

IPEndPoint ipe = new IPEndPoint(ip, port);//用指定的端口和ip初始化IPEndPoint类的新实例

/////创建socket并开始监听

Socket s = new Socket(AddressFamilyInterNetwork, SocketTypeStream, ProtocolTypeTcp);//创建一个socket对像,如果用udp协议,则要用SocketTypeDgram类型的套接字

sBind(ipe);//绑定EndPoint对像(2000端口和ip地址)

sListen(0);//开始监听

ConsoleWriteLine("等待客户端连接");

/////接受到client连接,为此连接建立新的socket,并接受信息

Socket temp = sAccept();//为新建连接创建新的socket

ConsoleWriteLine("建立连接");

string recvStr = "";

byte[] recvBytes = new byte[1024];

int bytes;

bytes = tempReceive(recvBytes, recvBytesLength, 0);//从客户端接受信息

recvStr += EncodingASCIIGetString(recvBytes, 0, bytes);

/////给client端返回信息

ConsoleWriteLine("server get message:{0}", recvStr);//把客户端传来的信息显示出来

string sendStr = "ok!Client send message successful!";

byte[] bs = EncodingASCIIGetBytes(sendStr);

tempSend(bs, bsLength, 0);//返回信息给客户端

tempClose();

sClose();

ConsoleReadLine();

}

}

}

客户端:

第一步:用指定的端口号和服务器的ip建立一个EndPoint对像;

第二步:建立一个Socket对像;

第三步:用socket对像的Connect()方法以上面建立的EndPoint对像做为参数,向服务器发出连接请求;

第四步:如果连接成功,就用socket对像的Send()方法向服务器发送信息;

第五步:用socket对像的Receive()方法接受服务器发来的信息 ;

第六步:通信结束后一定记得关闭socket;

代码:

using System;

using SystemCollectionsGeneric;

using SystemText;

using SystemNet;

using SystemNetSockets;

namespace Client

{

class Program

{

static void Main(string[] args)

{

try

{

int port = 2000;

string host = "127001";

/////创建终结点EndPoint

IPAddress ip = IPAddressParse(host);

//IPAddress ipp = new IPAddress("127001");

IPEndPoint ipe = new IPEndPoint(ip, port);//把ip和端口转化为IPEndpoint实例

/////创建socket并连接到服务器

Socket c = new Socket(AddressFamilyInterNetwork, SocketTypeStream, ProtocolTypeTcp);//创建Socket

ConsoleWriteLine("Conneting…");

cConnect(ipe);//连接到服务器

/////向服务器发送信息

string sendStr = "hello!This is a socket test";

byte[] bs = EncodingASCIIGetBytes(sendStr);//把字符串编码为字节

ConsoleWriteLine("Send Message");

cSend(bs, bsLength, 0);//发送信息

/////接受从服务器返回的信息

string recvStr = "";

byte[] recvBytes = new byte[1024];

int bytes;

bytes = cReceive(recvBytes, recvBytesLength, 0);//从服务器端接受返回信息

recvStr += EncodingASCIIGetString(recvBytes, 0, bytes);

ConsoleWriteLine("client get message:{0}", recvStr);//显示服务器返回信息

/////一定记着用完socket后要关闭

cClose();

}

catch (ArgumentNullException e)

{

ConsoleWriteLine("argumentNullException: {0}", e);

}

catch (SocketException e)

{

ConsoleWriteLine("SocketException:{0}", e);

}

ConsoleWriteLine("Press Enter to Exit");

}

}

}

先要理解socket是什么?

简单的说socket是一个全双工的通信通道,

即使用TCP或者UDP通信时均可以在发送消息的同时接受消息,

它不区分是否是服务器。

根据这个概念你的问题就很好回答。

》当客户端与服务器连接后。有什么方法使服务器可以随时随地发消息给客户端?

》我现在只能。客户端发个消息给服务器。服务器才能发个消息给客户端。也就是说客户端不发消息。服务器就没法发消息给客户端。

》求大牛给个思路。当连接后。客户端与服务器双方可以随时随地通信!

使用多线程,一个维持接受逻辑,一个维持送信逻辑,即可完成同时接受及发送。

客户端及服务器端均做上述设置。

而你的做法是在一个线程中执行接受与送信,因此只能按照顺序逻辑完成接收与送信。

关键点是多线程。

搭建外网访问,首先你要有一台外网可访问的服务器,有以下几种方法可以实现。

一、购买外网服务器。由于服务器端使用JAVA语言开发,所以外网服务器操作系统可以是Linux或Windows,这个需要你花钱购买。如果只是测试,你可以选择购买阿里云的云服务器,非常便宜。

二、还有一种方法就是你通过花生壳之类的软件进行映射你的网络,但花生壳对长城宽带之类的网络支持不是特别好,如果需要很好的支持,那也需要花钱购买。

三、如果你是通过路由器上网,并且可以操作路由器权限且使用的是电信或者是联通的网络,那可以直接在路由器里面做端口映射,这个你可以百度一下,有很多文章讲的非常清楚,这里篇幅限制,就不贴了。

四、如果你是直接通过猫上网且使用电信或联通宽带,那可以直接使用本机外网IP访问你的程序。

以上四种方法中,最稳定的还是购买外网服务器,其它都会有各种问题,你可以选择其中适合你的一种方法。希望能帮助到你

众所周知TCP(Transmission Control Protocol )是一种面向连接的、可靠的、基于字节流的通信协议。而开发TCP socket应用程序是一件比较简单的事情。下面就用一个比较简单的demo 讲解开发的过程。

该程序分为客户端和服务器端,客户端主要是向服务器端发送数据,服务器端主要是对于接收的数据进行显示。

TCP服务器端和客户端的主要流程:

服务器端:1 创建套接字 2 绑定 3 监听 4 接受连接 5 收发数据 6 关闭

客户端: 1 创建套接字 2 连接 3 收发数据 4 关闭

实现中用到的主要函数及

服务器: 1 WSAStartup() 2 socket() 3 bind() 4 listen() 5 accept() 6 recv() 7 closesocket() 8 WSACleanup()

客户端: 1 WSAStartup() 2 socket() 3 connect() 4 send() 5 closesocket() 6 WSACleanup()

下面是server 和 client 的实现代码,运行的时候首先启动server,然后再启动client, 则在server部分打印出“hello world” 。

DABAN RP主题是一个优秀的主题,极致后台体验,无插件,集成会员系统
网站模板库 » C++网络编程(socket)我要写一个服务器端程序和一个客户端程序

0条评论

发表评论

提供最优质的资源集合

立即查看 了解详情