网络编程之基于TCP 的Sockets编程

百度百科言:多个TCP连接或多个应用进程进程可能需要通过同一个 TCP协议端口传输数据。为了区别不同的应用程序进程和连接,许多计算机操作系统为应用程序与TCP/IP协议交互提供了称为套接字(Socket)的接口。简单的说套接字就是一种支持TCP/IP的网络通信的基本操作单元,可以看做是不同主机之间的进程进行双向通信的端面点,也就是通信的两方的一种约定,用套接字中的相关函数来完成通信过程。 常用的TCP/IP协议套接字有三种,分别是:

流套接字(SOCK_STREAM):   流套接字用于提供面向连接、可靠的数据传输服务。该服务将保证数据能够实现无差错、无重复发送,并按顺序接收。流套接字之所以能够实现可靠的数据服务,原因在于其使用了传输控制协议,即TCPThe Transmission Control Protocol)协议。   

数据报套接字(SOCK_DGRAM):数据报套接字提供了一种无连接的服务。该服务并不能保证数据传输的可靠性,数据有可能在传输过程中丢失或出现数据重复,且无法保证顺序地接收到数据。数据报套接字使用UDPUser Datagram Protocol)协议进行数据的传输。由于数据包套接字不能保证数据传输的可靠性,对于有可能出现的数据丢失情况,需要在程序中做相应的处理。   

原始套接字(SOCK_RAW):原始套接字与标准套接字(标准套接字指的是前面介绍的流套接字和数据报套接字)的区别在于:原始套接字可以读写内核没有处理的IP数据包,而流套接字只能读取TCP协议的数据,数据报套接字只能读取UDP协议的数据。因此,如果要访问其他协议发送数据必须使用原始套接字。

我们如果想要用套接字实现网络通信,那就应该至少需要一对,一个在服务器端(ServerSocket),一个则运行在客户端(ClientSocket)。而套接字的连接建立过程由服务器监听、客户端请求和连接确认三个步骤完成。使用套接字进行数据处理有同步模式和异步模式,两者的不同点就在于前者只适合用于数据处理不太多的场合,而后者比较适合于进行大量数据处理的场合。

windows网络编程均是由windows套接字实现,经常用到的是MFC类库中的CSocket类。使用该类的基本流程如下:

创建套接字———>绑定地址信息———>连接服务器———>数据交换

———>关闭套接字对象。

下面用VC6实现同步模式下的一个简单例子:

首先建立的是服务器端:

#include <winsock2.h>	//包含头文件
#include <stdio.h>
#include <windows.h>
#pragma comment(lib,"WS2_32.lib");//显示连接套接字库
int main()
{
	WSADATA data;//定义结构体对象
	WORD w=MAKEWORD(2,0);//定义版本号码
	char sztext[]="欢迎你\r\n";//定义并初始化发送到客户端的字符数组
	::WSAStartup(w,&data);//初始化套接字库
	SOCKET s,s1;//定义连接套接字和数据收发套接字句柄
	s=::socket(AF_INET,SOCK_STREAM,0);//创建TCP套接字
	sockaddr_in addr,addr2;//定义套接字地址结构
	int n=sizeof(addr2);//获取套接字地址结构大小
	addr.sin_family=AF_INET;//初始化地址结构
	addr.sin_port=htons(75);
	addr.sin_addr.S_un.S_addr=INADDR_ANY;
	::bind(s,(sockaddr*)&addr,sizeof(addr));//绑定套接字
	::listen(s,5);//监听套接字
	printf("服务器已经启动...........\r\n");
	while(true)
	{
		s1=::accept(s,(sockaddr*)&addr2,&n);//接受连接请求
		if(s1!=NULL)
		{
			printf("%s已经连接上...........\r\n",inet_ntoa(addr2.sin_addr));
			::send(s1,sztext,sizeof(sztext),0);//向客户端放送字符数组
		}
		::closesocket(s);//关闭套接字句柄
		::closesocket(s1);
		::WSACleanup();//释放套接字
		if(getchar())//如果有输入则关闭程序
		{
			return 0;//正常结束程序
		}
		else
		{
			::Sleep(100);//应用睡眠0.1秒
		}
	}
	return 0;
}

然后建立客户端:

#include <winsock2.h>	//包含头文件
#include <stdio.h>
#include <windows.h>
#pragma comment(lib,"WS2_32.lib");//显示连接套接字库
int main()
{
	WSADATA data;//定义结构体对象
	WORD w=MAKEWORD(2,0);//定义版本号码
	::WSAStartup(w,&data);//初始化套接字库
	SOCKET s;//定义连接套接字和数据收发套接字句柄
	char sztext[10]={0};
	s=::socket(AF_INET,SOCK_STREAM,0);//创建TCP套接字
	sockaddr_in addr,addr2;//定义套接字地址结构
	int n=sizeof(addr2);//获取套接字地址结构大小
	addr.sin_family=AF_INET;//初始化地址结构
	addr.sin_port=htons(75);
	addr.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
	printf("客户端已经启动....\r\n");
	::connect(s,(sockaddr*)&addr,sizeof(addr));
	::recv(s,sztext,sizeof(sztext),0);
	printf("%s\r\n",sztext);
	::closesocket(s);
	::WSACleanup();
	if(getchar())
	{
		return 0;
	}
	else
	{
		::Sleep(100);
	}
}

运行服务器端和客户端程序,可以知道服务器和客户端已经启动,客户端也成功的接受到了服务器发送的字符数组。



 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值