回射程序(客户端)——客户接收一行数据

来源:互联网 发布:22岁学钢琴知乎 编辑:程序博客网 时间:2024/04/27 23:12

基于流式套接字的服务器回射程序设计。

编写一服务器程序和客户程序,要求客户每输入一行数据,服务器接收后加上echo:回送给客户程序,当客户输入“q”后退出。



该回射程序的设计思路如上图。客户端接收数据时使用recvline接收一行数据。判断的标准是接收到“\n”即为接收到一行

其中,recvline的设计有两种思路:

1)使用循环,每次调用recv(),接收一个字节,判断是否为“\n”

2)使用循环,将数据先全部接收到缓存区中,再从缓存区中一个一个字符判断是否为“\n”

在这里使用第二种思路来实现recvline

// 回显客户端1.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include<stdio.h>#include <stdlib.h>#include <string.h>#include <WinSock2.h>#pragma  comment(lib,"wsock32.lib")#define  MAXSIZE 100int getline(char* s,int max);BOOL recvline(SOCKET S,char* buf);int _tmain(int argc, _TCHAR* argv[]){//初始化WinSockWSADATA wsaData;int ret = WSAStartup(MAKEWORD(2,2),&wsaData);if(ret != 0){printf("WSAStratup failed!code:%d\n",WSAGetLastError());return -1;}if(LOBYTE(wsaData.wVersion)!=2||HIBYTE(wsaData.wVersion)!=2){WSACleanup();printf("Invaild WinSock Version\n");return -1;}//建立客户端套接字SOCKET sockclient;sockclient = socket(AF_INET,SOCK_STREAM,0);if(sockclient==INVALID_SOCKET){WSACleanup();printf("socket() failed!code:%d\n",WSAGetLastError());return -1;}//服务器地址信息struct sockaddr_in saServer;saServer.sin_family = AF_INET;saServer.sin_port=htons(6000);saServer.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");//连接服务器ret = connect(sockclient,(sockaddr*)&saServer,sizeof(saServer));if(ret == SOCKET_ERROR){printf("connect() failed!code:%d\n",WSAGetLastError());closesocket(sockclient);WSACleanup();return -1;}elseprintf("connect successed\n");//向服务器发送数据char buff[MAXSIZE];char recvbuff[MAXSIZE];memset(buff, 0 , MAXSIZE);memset(recvbuff,0,MAXSIZE);while (strcmp(buff, "q") != 0) {printf("Please input a string to send:\n");getline(buff,MAXSIZE);if(send(sockclient, buff, sizeof(buff), 0) <= 0) {printf("send failed !code:%d\n",WSAGetLastError());closesocket(sockclient);WSACleanup();return -1;}if(!recvline(sockclient,recvbuff)){closesocket(sockclient);WSACleanup();return -1;}//打印收到的回显字符串printf("%s\n",recvbuff);}closesocket(sockclient);WSACleanup();return 0;}int getline(char *s, int max){int i = 0;char c;while (--max >0 && (c = getchar()) != EOF && c != '\n')s[i++] = c;if (c = '\n')s[i] = '\n';return i;}/********************************************************/*函数作用:接收一行数据/*参数说明:连接套接字、接收缓存/*返回值:成功返回TRUE,失败返回FALSE/********************************************************/BOOL recvline(SOCKET S,char* buf){BOOL retval = TRUE; //返回值BOOL bLineEnd = FALSE;//一行读取结束int nReadLen = 0; //读入字节数int nDataLen = 0; //数据长度while(!bLineEnd){nReadLen = recv(S,buf,MAXSIZE,0);if(nReadLen == SOCKET_ERROR){int nErrCode = WSAGetLastError();   // 获取错误代码  if(WSAENOTCONN == nErrCode)  {  printf("套接字没有连接\n");  } else if(WSAESHUTDOWN == nErrCode)  {  printf("套接字已经关闭\n");  } else if(WSAETIMEDOUT == nErrCode)  {  printf("请求超时,主机没有反应\n");  } else if(WSAECONNRESET == nErrCode)  {  printf("远程主机强迫关闭了现有的连接\n");  } else {}  retval = FALSE;   // 读取数据失败  break;              // 跳出循环  }if(0==nReadLen){retval = FALSE; //读取数据失败break;}for(int i=0;i<nReadLen;i++){if('\n' == *(buf+i))bLineEnd = TRUE;}}return retval;}




0 0
原创粉丝点击