Winsocket通信测试

来源:互联网 发布:奔驰s600电脑编程 编辑:程序博客网 时间:2024/06/08 11:59

在学习网络编程之前,我们需要对Tcp/ip协议栈有个清楚地了解。Tcp/ip协议栈分以下五层,也有分成7层

 5、应用层
    4、传输层
    3、网络层
    2、数据链路层
    1、物理层

物理层是实实在在的物理链路,它为上层协议提供了一个传输数据的物理媒体,负责将数据以比特流的方式收发、接收。数据链路层主要负责物理传输的准备,MAC地址和交换机都工作在这一层。网络层主要负责管理网络地址、定位设备、决定路由。路由器就工作在这一层。作用是将网路地址翻译成物理地址,并决定将数据从发送方路由到接收方。应用层,一般是指应用程序,该层主要负责确定通信对象,并确保有足够资源用于通信。根据传输层的端口信息调用不同的程序来处理传输的内容,端口8080是http报文,端口21是ftp报文。

物理层关心的是如何把电气信号变成一段报文;数据链路层关心的是mac地址、vlan、优先级等;网络层关心的是ip地址,下一跳ip;传输层关心的是端口资源;应用层关心的是报文组装、解析、渲染、存储、执行等等。

在学习网络编程之前,学习socket的工作原理是很有必要的。我们需要为它配置端口信息和ip地址。配置完了之后,我们就可以慢慢等待报文的收发了。所以一般来说,作为服务器端口的处理流程是这样的:

 a) 创建socket b) 绑定socket到特定的ip地址 c) 对socket进行侦听处理 d) 接受socket,表明有客户端和服务器连接 e) 和客户端循环收发报文 f) 关闭socket
客户端的处理流程就相对简单一点了,只需要a) 创建socketb) 链接服务器端地址c) 和服务器端的socket收发报文

一、Winsocket用TCP协议来完成通信


①服务器的程序

// SocketSever.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include <Winsock2.h>#include <stdio.h>#include <stdlib.h>#pragma comment(lib,"WS2_32.LIB")#if DUBUG  #define AF_INET         2               /* internetwork: UDP, TCP, etc. */#define SOCK_STREAM     1               /* stream socket */#define SOCK_DGRAM      2               /* datagram socket */#define SOCK_RAW        3               /* raw-protocol interface */#define SOCK_RDM        4               /* reliably-delivered message */#define SOCK_SEQPACKET  5               /* sequenced packet stream *//** Socket address, internet style.*/struct sockaddr_in {short   sin_family;u_short sin_port;struct  in_addr sin_addr;char    sin_zero[8];};typedef struct sockaddr_in SOCKADDR_IN; /* Microsoft Windows Extended data types */int bind(SOCKET s,const struct sockaddr FAR * name,int namelen);/* INCL_WINSOCK_API_PROTOTYPES*/int listen(SOCKET s,int backlog);#endif #define Port 3578#define MaxSize 1024SOCKADDR_IN addrSrv;SOCKADDR_IN addrClient;SOCKET sockSrv; //服务器SOCKET sockConn;//********************************************************************************************************///** 函数名 ** StartSock()//**  输入  ** 无//**  输出  ** 无//**函数描述** 加载套接字//********************************************************************************************************/int SocketInit(){WORD wVersionRequested;WSADATA wsaData;int err;wVersionRequested=MAKEWORD(2,2);err = WSAStartup(wVersionRequested,&wsaData); //返回0,成功,否则就是错误码if (err!=0){printf("WinSock DLL版本不足要求n");return 0;}if (LOBYTE(wsaData.wVersion)!=2||HIBYTE(wsaData.wVersion)!=2){WSACleanup();return 0;}return 1;}//********************************************************************************************************///** 函数名 ** main()//**  输入  ** 无//**  输出  ** 无//**函数描述** 主函数//********************************************************************************************************/int main(){ if (SOCKET_ERROR ==SocketInit()) { return -1; }SOCKADDR_IN addrSrv;//存放本地地址信息的addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);//htol将主机字节序long型转换为网络字节序addrSrv.sin_family=AF_INET;addrSrv.sin_port=htons(6001);//htos用来将端口转换成字符,1024以上的数字即可//真正socket编程部分SOCKET sockSrv=socket(AF_INET,SOCK_STREAM,0);//面向连接的可靠性服务SOCK_STRAMbind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));//将socket绑定到相应地址和端口上listen(sockSrv,5);//等待队列中的最大长度为5printf("%s\n","Welcome,the Host is running!Now Wating for someone comes in!");SOCKADDR_IN addrClient;int iSend = 0;char sendBuf[MaxSize];char revBuf[MaxSize];int len=sizeof(SOCKADDR);while(1)//循环监听客户端,永远不停止{sockConn=accept(sockSrv,(SOCKADDR*)&addrClient,&len);//阻塞调用进程直至新的连接出现if(sockConn == INVALID_SOCKET){printf("Accept Failed!\n");return -1;}sprintf(sendBuf,"Server IP is:%s",inet_ntoa(addrClient.sin_addr));//inet_nota函数是将字符转换成ip地址iSend = send(sockConn,sendBuf,strlen(sendBuf)+1,0);//服务器向客户端发送数据if(iSend == SOCKET_ERROR){printf("send Failed!");break;}char recvBuf[100];recv(sockConn,recvBuf,100,0);//服务器从客户端接受数据printf("%s\n",recvBuf);closesocket(sockConn);//关闭socket}closesocket(sockConn);         //关闭套接字getchar();return 0;}
②客户端的程序

<pre name="code" class="cpp">#include "stdafx.h"#include <Winsock2.h>#include <stdio.h>#include <string.h>#pragma comment(lib,"WS2_32.LIB")//********************************************************************************************************///** 函数名 ** StartSock()//**  输入  ** 无//**  输出  ** 无//**函数描述** 加载套接字//********************************************************************************************************/int SocketInit(){WORD wVersionRequested;WSADATA wsaData;int err;wVersionRequested=MAKEWORD(2,2);err = WSAStartup(wVersionRequested,&wsaData); //返回0,成功,否则就是错误码if (err!=0){printf("WinSock DLL版本不足要求n");return 0;}if (LOBYTE(wsaData.wVersion)!=2||HIBYTE(wsaData.wVersion)!=2){WSACleanup();return 0;}return 1;}//********************************************************************************************************///** 函数名 ** main()//**  输入  ** 无//**  输出  ** 无//**函数描述** 主函数//********************************************************************************************************/int main(){    //固定格式    char recvBuf[1024];if (SOCKET_ERROR ==SocketInit()) { return -1; }    //建立通讯socket    SOCKET sockClient=socket(AF_INET,SOCK_STREAM,0);    SOCKADDR_IN addrSrv;    addrSrv.sin_addr.S_un.S_addr=inet_addr("192.168.1.100");//设定需要连接的服务器的ip地址    addrSrv.sin_family=AF_INET;    addrSrv.sin_port=htons(6001);//设定需要连接的服务器的端口地址    connect(sockClient,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));//与服务器进行连接    //接受来自老师的信息  int iRevLen = 0;    iRevLen = recv(sockClient,recvBuf,strlen(recvBuf)+1,0);if(0 == iRevLen){return -1;}else if(SOCKET_ERROR == iRevLen){printf("Recv Failed\n!");return -1;}    printf("%s\n",recvBuf);char str[100];gets(str);    send(sockClient,str,strlen(str)+1,0);closesocket(sockClient);    WSACleanup();getchar();return -1;}


1 0