面向对象Socket网络程序设计(含代码)

本例采用SOCKET类来创建流式套接字(基于传输层TCP协议)

实验环境为VC++6.0

步骤:

1.新建一个工作区

2.新建一个Win32 Console Application工程,这里需注意要勾选加入现有的工作区

3.新建一个源文件,类型为c++ Source File,添加到工程中

4.写代码(两台主机网络层要互通)

服务端代码 

#include<WinSock2.h>
#include<stdio.h>
#pragma comment(lib,"WS2_32.LIB")

void main()
{
	WORD wVersionRequested;
	WSADATA wsaData;
	int err;

	wVersionRequested=MAKEWORD(1,1);
	err=WSAStartup(wVersionRequested,&wsaData);

	if(err!=0)
	{
		return;
	}

	if(LOBYTE(wsaData.wVersion)!=1||HIBYTE(wsaData.wVersion)!=1)
	{
		WSACleanup();
		return;
	}
    //创建用于监听的套接字
	SOCKET sockSrv=socket(AF_INET,SOCK_STREAM,0);//创建流式套接字
	SOCKADDR_IN addrSrv;
	addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);//获取本主机IP地址
	addrSrv.sin_family=AF_INET;
	addrSrv.sin_port=htons(6000);//设置本服务端口号6000

    //绑定套接字
	bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));

    //将套接字设置为监听模式,接收客户端请求
	listen(sockSrv,5);

    
	SOCKADDR_IN addrClient;
	int len=sizeof(SOCKADDR);
	printf("This is the Server.\n");

	while(1)  //等待客户请求到来
	{
		SOCKET sockConn=accept(sockSrv,(SOCKADDR*)&addrClient,&len);
		char sendBuf[100];
		printf("Now,client:%s已连接本服务器!\n",inet_ntoa(addrClient.sin_addr));
		sprintf(sendBuf,"This is from the serve,welcome %s to Serve!",inet_ntoa(addrClient.sin_addr));
        
        //发送数据
        send(sockConn,sendBuf,strlen(sendBuf)+1,0);
		char receBuf[100];
        //接收数据
		recv(sockConn,receBuf,100,0);
		printf("%s\n",receBuf);
		closesocket(sockConn);  //关闭套接字


	}
}

客户端代码 

#include<WinSock2.h>
#include<stdio.h>
#pragma comment(lib,"WS2_32.LIB")
void main()
{
	WORD wVersionRequested;
	WSADATA wsaData;
	int err;

	wVersionRequested=MAKEWORD(1,1);

	err=WSAStartup(wVersionRequested,&wsaData);
	if(err!=0)
	{
		return;
	}
	if(LOBYTE(wsaData.wVersion)!=1||HIBYTE(wsaData.wVersion)!=1)
	{
		WSACleanup();
		return;
	}

    //创建套接字
	SOCKET sockClient=socket(AF_INET,SOCK_STREAM,0); //创建流式套接字
	SOCKADDR_IN addrSrv;
	addrSrv.sin_addr.S_un.S_addr=inet_addr("172.16.8.45");//指出服务端IP地址
	addrSrv.sin_family=AF_INET;
	addrSrv.sin_port=htons(6000);//指出服务端的端口号
	printf("This is client(172.16.8.46)\n");

	connect(sockClient,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));  //向服务器发出连接请求

	char receBuf[100];
	recv(sockClient,receBuf,100,0);
    //发送数据
	send(sockClient,"Hello,this is from client1",strlen("Hello,this is from client1")+1,0);

      //关闭套接字
	closesocket(sockClient);
	WSACleanup();

}

5.点红色感叹号运行

实验结果

客户端显示

服务端显示

 wireshark抓包观察TCP报文

 

TCP建立连接的三次握手(指连接建立过程中通信双方交互3个报文),请求-确认-再确认,

1.客户机向服务器发送连接请求报文段,其中SYN为1,seq为0(即i=0);

2.服务器同意连接,回答确认报文段,其中SYN=1,ACK=1,序列号seq=0(即j=0),确认号ack=1(i+1=1);

3.客户机向服务器再回送确认,确认报文段首部中ACK=1,确认号ack=1(j+1=1),序列号seq=1(i+1=1)。

TCP连接释放的四次握手

1.客户机向服务器发出连接释放报文段,其首部中FIN=1,,序列号seq=28(即u=28),确认号ack=54(即v=54),序列号为已传达的数据的最后一字节的序号+1,表示发送数据已结束,主动关闭TCP连接;

2.服务器接收到后,同意则回答确认报文段,首部中ACK=1,序列号seq=54(v),确认号ack=29(u+1=29),此后,服务器不再接受客户机数据,但服务器仍可向客户机发送数据;

3.若服务器无需向客户机发送数据,则向客户机发送连接释放报文段,确认号ack=29(u+1),序列号seq=54(v),且首部中FIN=1,ACK=1;

4.客户机接收到连接释放报文段后,发出确认,确认号ask=55(v+1),序列号seq=29(u+1),其首部的ACK=1。

  • 14
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值