Windows下使用TCP协议变长交互客户端和服务器的数据传输
2016-12-21 22:55
936 查看
之前有提及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;
}
其是在定长数据传输的基础上,双方发送的数据中不含了一个结构化的头部信息。如:
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;
}
相关文章推荐
- 使用TCP协议连续传输大量数据时,是否会丢包,应如何避免?
- 使用TCP协议连续传输大量数据时,是否会丢包,应如何避免?
- TCP数据传输(四):上传文件操作(将客户端的文件发送到服务器)
- tcp协议服务器和客户端相互发送数据
- 【转】使用TCP协议连续传输大量数据时,是否会丢包,应如何避免?
- Android客户端使用HttpURLConnection doGet与服务器数据交互简单示例
- 【代码练习5】使用套接字实现客户端和服务器的数据传输
- 程序使用 HTTP 协议和服务器交互主要是进行数据的提交,通常数据的提交是通过 GET 和 POST 两种方式来完成
- 客户端与服务器进行数据传输时的TCP窗口与拥塞处理
- 【转】使用TCP协议连续传输大量数据时,是否会丢包,应如何避免?
- Android客户端与服务器HTTP交互,数据以json格式传输
- Android网络应用之使用Scoket的Android客户端与TCP服务器的简单交互
- 传输层TCP协议——TCP服务器/客户端
- 客户端C和服务器S之间建立一个TCP连接,该连接总是以1KB的最大段长发送TCP段,客户端C有足够的数据要发送。当拥塞窗口为16KB的时候发生超时,如果接下来的4个RTT往返时间内的TCP段的传输是成
- TCP服务器和多个客户端传输数据
- WCF 通过net tcp 协议 ,在服务端服务器和客户端服务器之间传输数据,注意配置事项
- 【转】使用TCP协议连续传输大量数据时,是否会丢包,应如何避免?
- Android使用Socket(Tcp/Udp)协议进行数据传输(传输大文件)
- 关于客户端与服务器ajax使用json数据交互,出现中文乱码或因包含html标答而报错的问题(base64加密)
- 使用TCP协议实现客户端和服务器数据传输