VC++中Socket编程的实现---【TCP服务器端】
来源:互联网 发布:农行网银支持mac吗 编辑:程序博客网 时间:2024/05/21 16:01
Socket在TCP服务器端
预备:
加载套接字库。
过程:
1.创建套接字(socket)。
2.将套接字绑定到一个本地地址和端口上(bind)。
3.将套接字设为监听模式,准备接受客户请求(listen)。
4.等待客户请求到来;当请求到来后,接受连接请求,返回一个新对应于此次连接的套接字(accept)。
5.用返回的套接字和客户端进行通讯(send/recv)。
6.返回等待另一客户请求。
7.关闭套接字。
实现:
//加载套接字库
#include <Winsock2.h>#include <stdio.h>//还需要添加链接库ws2_32.lib(工程=设置=链接=对象/库模块)WORD wVersionRequested; //准备加载Winsock库的版本,注意高字节是副版本号WSADATA wsaData; //是一个返回值,指向WSADATA结构的指针,WSAStartup函数将其加载的库版本信息输入到这个结构体中。int err;wVersionRequested = MAKEWORD(1,1);err = WSAStartup(wVersionRequested,&wsaData);if(0 != err){ return;}if(LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1){ WSACleanup(); //如果加载的版本不正确,返回。需要注意的是高字节是副版本号,低字节是主版本号 return;}
//跟着步骤实现套接字
1.创建套接字
socket(int af,int type,int protocol); //socket 函数三个参数af,指定地址族,对于TCP/IP协议套接字,它只能是AF_INET;type参数指定Socket类型,对于1.1版本的Socket,它只支持两种类型的套接字,SOCK_STREAM指定产生流失套接字,SOCK_DGRAM产生数据报套接字;protocol是与特定的地址家族相关的协议,如果指定为0,那么系统就会根据地址格式和套接字类别,自动选择一个合适的协议。
SOCKET sockSrv = socket(AF_INET,SOCK_STREAM,0);
2.绑定一个端口到套接字上
SOCKADDR_IN addrSrv; addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY); addrSrv.sin_family=AF_INET; addrSrv.sin_port=htons(6000); bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR)); int bind(SOCKET s,const struct sockaddr FAR *name,int namelen);
//s为指定要绑定的套接字;name指定了该套接字的本地地址信息,这是一个指向sockaddr结构的指针变量,该地址结构是为所有的地址家族准备的,这个结构可能随时用的网络协议不同而不同,所以才需要第三个参数namelen指定该地址结构的长度。
sockaddr结构的定义如下:
struct sockaddr{ u_short sa_family; char sa_data[14];};
其中sa_family指定地址家族,对于TCP/IP协议的套接字,必须设置为AF_INET,sa_data[14]只是一个占位的作用,该区域中指定与协议相关的具体地址信息。由于实际要求只是内存区,所以对不同的协议家族,用不同的结构来替换sockaddr。除了sa_family外,sockadd是按网络字节顺序表示的。在基于TCP/IP的socket编程中,可以使用sockaddr_in结构替换sockaddr,以方便我们填写地址信息。
struct sockaddr_in{ short sin_family; unsigned short sin_port; //Port 2 Bytes! struct in_addr sin_addr; //Address 4 Bytes! char sin_zero[8]; //8 Bytes!};
sockaddr_in和sockaddr的长度是一样的。
需要注意的是sin_addr的类型是in_addr,而in_addr实际上是一个联合
struct in_addr{ union{ struct{u_char s_b1,s_b2,s_b3,s_b4;}S_un_b; struct{u_short s_w1,s_w2;}S_un_w; u_long S_addr; }S_un;};
所以才有了上面的 addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
INADDR_ANY,表示的是所有IP!
3.将套接字设为监听模式
listen(sockSrv,5);
// int listen(SOCKET s,int backlog); s是Socket不用说,backlog是等待队列的最大长度,比如现在设为2,那么假如同时有3个请求来到服务器端的时候,就把前两个放到请求队列中,第三个就会被拒绝。
4.等待客户请求到来,返回连接套接字和通讯
SOCKADDR_IN addrClient; int len=sizeof(SOCKADDR); while(1) { SOCKET sockConn=accept(sockSrv,(SOCKADDR*)&addrClient,&len); //建立连接,返回对应于此次连接的SOCKET char sendBuf[100]; //发送数据的buff sprintf(sendBuf,"Welcome %s to my space!", inet_ntoa(addrClient.sin_addr)); //格式化客户端地址 send(sockConn,sendBuf,strlen(sendBuf)+1,0); //发送的字节多一个,最后一个是空,结束! char recvBuf[100]; //接收数据的buff recv(sockConn,recvBuf,100,0); //接收数据 printf("%s/n",recvBuf); closesocket(sockConn); //关闭连接 }
//accept();这个函数是用来接受客户端发送的连接请求,并返回建立连接的Socket:
SOCKET accept( SOCKET s, struct sockaddr FAR* addr, int FAR* adrlen);
s表示已经通过listen函数设为监听状态的SOCKET!addr是指向缓冲区的指针,保存发起连接的这个客户端的IP地址信息和端口信息;addrlen是addr的长度。
//send函数通过一个已经建立连接的套接字发送数据,recv是通过一个已经建立连接的套接字接收数据。两个函数的参数基本一样。
int send(SOCKET s,const char FAR* buf,int len,int flags);
不同的只有buf,对于send那是发送数据的buf,而对于recv那是接收数据的buf,flags通常情况下为0.
注意上面用了一个函数inet_ntoa是格式化IP地址的,将接受一个ULONG型的数据返回一个被格式化成了点分的字符串的IP(如:192.168.0.1),还有一个inet_addr作用和inet_ntoa正好相反。
- VC++中Socket编程的实现---【TCP服务器端】
- VC++中Socket编程的实现-TCP服务器端
- VC++中Socket编程的实现-TCP服务器端
- VC++中Socket编程的实现---【TCP客户端】
- VC++中Socket编程的实现-TCP客户端
- 基于TCP的客户端、服务器端socket编程
- 【Java Socket】入门系列 3.2.编程实现基于 TCP 的 Socket 通信 — 服务器端和客户端
- 基于C#的socket编程的TCP异步实现 ,包含服务器端与客户端源代码
- vc socket tcp编程的简单实例
- C++ 简单的 Tcp 实现[socket] 服务器端与客户端通信
- VC++中Socket编程的实现-UDP客户端
- 实现服务器端的多线程SOCKET Server C++/VC 【转】
- 实现服务器端的多线程SOCKET Server C++/VC
- 实现服务器端的多线程SOCKET Server C++/VC
- 实现服务器端的多线程SOCKET Server C++/VC
- 编程实现基于tcp的socket编程
- MFC Socket网络编程之TCP服务器端
- Socket实现TCP编程
- router loopback 接口解释
- [转]简述CMMI 2级的7个PA
- vc判断数据库中是否有表
- 对BS开发技术发展的一点理解(微软体系)
- jquery源码阅读知识储备(9)javascrpt中的闭包和Currying(待续)
- VC++中Socket编程的实现---【TCP服务器端】
- 关于setOnClickListenter()
- VC++中Socket编程的实现---【TCP客户端】
- Linux cpufreq 机制
- the process of developing a program
- ORA-01861: 文字与格式字符串不匹配
- oscache的用法
- OSCache入门教程
- Windows Phone 7 优秀开源项目概览