Windows下使用TCP协议变长交互客户端和服务器的数据传输

来源:互联网 发布:淘宝网店赚钱 编辑:程序博客网 时间:2024/05/22 01:58

之前有提及Windows下交互式服务器和客户端进行定长的数据传输,但是这样会存在浪费的情况,所以今天就上传以前课堂上学习过的变长数据传输。

其是在定长数据传输的基础上,双方发送的数据中不含了一个结构化的头部信息。如:

struct{     unsigned int reclen;     char buf =[MAXLINE];   }packet;

跟前面的工程一样,服务器和客户端各自的工程中都包含着SocketFrame.h和SocketFrame.cpp这两个文件,我这里就不再写上去。主要就写服务器数据传输源码和客户端的数据传输源码。

服务器:

// EchoTCPServer.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include "SocketFrame.h"#include "winsock2.h"#define ECHOPORT "7210"int tcp_server_fun_recvn( SOCKET s ,int flen);int main(int argc, char* argv[]){CSocketFrame frame;int iResult = 0;SOCKET ListenSocket, ConnectSocket;int nlen =0;//输入参数合法性检查if (argc != 2){printf("usage: EchoTCPServer-recvn <定长接收长度>");return -1;}//char *len =*argv[1];nlen = atoi(argv[1]);if ( nlen <= 0 ){printf("不正确的输入:<定长接收长度>!");return -1;}//Windows Sockets Dll初始化frame.start_up();//创建服务器端的流式套接字并在指定端口号上监听ListenSocket = frame.tcp_server( NULL, ECHOPORT );if ( ListenSocket == -1 )return -1;    printf("服务器准备好回射服务。。。\n");for ( ; ; ) {        ConnectSocket = accept( ListenSocket, NULL, NULL );if( ConnectSocket != INVALID_SOCKET ){//建立连接成功printf("\r\n建立连接成功\n\n");//定长接收数据iResult = tcp_server_fun_recvn( ConnectSocket,nlen);//如果出错,关闭当前连接套接字,继续接收其它客户端的请求if(iResult == -1)printf("当前连接已关闭或出错!\n");}else{printf("accept 函数调用错误,错误号: %d\n", WSAGetLastError());            frame.quit( ListenSocket );            return -1;        }//关闭连接套接字if ( closesocket( ConnectSocket ) == SOCKET_ERROR)        printf("closesocket 函数调用错误,错误号:%d\n", WSAGetLastError());;}frame.quit( ListenSocket );    return 0;}/********************************************************函数名:tcp_server_fun_recvn输入参数:SOCKET s:服务器的连接套接字          int flen:指定接收长度输出参数:0:成功,-1:失败功能:tcp_server:定长接收数据并统计字节数********************************************************/int tcp_server_fun_recvn( SOCKET s ,int flen){CSocketFrame frame;int iResult = 0;char    recvline[MAXLINE];do {memset( recvline, 0, MAXLINE );//接收定长数据     iResult = frame.recvn( s, recvline, flen);if (iResult > 0){printf("服务器端接收到%d字节的数据:%s\n", iResult,recvline);}else{if (iResult == 0)             printf("对方连接关闭,退出\n");    else{             printf("recv 函数调用错误,错误号: %d\n", WSAGetLastError());    iResult = -1;}} } while (iResult > 0);return iResult;}


客户端:

// EchoTCPClient.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include "SocketFrame.h"int tcp_client_fun_recvn(FILE *fp,SOCKET s);#define ECHOPORT "7210"int main(int argc, char* argv[]){CSocketFrame frame;int iResult;SOCKET ClientSocket;//输入参数合法性检查if (argc != 2){printf("usage: EchoTCPClient-recvn <IPaddress>");return -1;}//Windows Sockets Dll初始化frame.start_up();//创建客户端的流式套接字,并与服务器建立连接    printf("连接建立成功,请输入回射字符串。。。\n");ClientSocket = frame.tcp_client( ( char *)argv[1], ECHOPORT );if ( ClientSocket == -1 )return -1;//开始回射请求的发送与接收iResult = tcp_client_fun_recvn(stdin,ClientSocket);frame.quit( ClientSocket );    return iResult;return 0;}/********************************************************函数名:tcp_client_fun_recvn输入参数:FILE *fp:指向FILE类型的对象          SOCKET s:服务器的连接套接字输出参数:0:成功,-1:失败功能:测试服务器定长接收能力,根据用户输入,持续向服务器发送数据*********************************************************/int tcp_client_fun_recvn(FILE *fp,SOCKET s){int iResult;    char sendline[MAXLINE],recvline[MAXLINE];memset(sendline,0,MAXLINE);memset(recvline,0,MAXLINE);//循环发送用户的输入数据,并接收服务器返回的应答,直到用户输入"Q"结束while(fgets(sendline,MAXLINE,fp)!=NULL){if( *sendline == 'Q'){printf("input end!\n");// 数据发送结束,调用shutdown()函数声明不再发送数据,此时客户端仍可以接收数据iResult = shutdown(s, SD_SEND);if (iResult == SOCKET_ERROR) {printf("shutdown failed with error: %d\n", WSAGetLastError());}return 0;}iResult = send(s,sendline,strlen(sendline),0);if(iResult == SOCKET_ERROR){printf("send 函数调用错误,错误号: %ld\n", WSAGetLastError());return -1;}printf("\r\n客户端发送数据:%s\r\n", sendline);memset(sendline,0,MAXLINE);}return iResult;}


0 0
原创粉丝点击