当前位置:编程学习 > C/C++ >>

关于C++ TCP/IP通信的问题

// winsockClient.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "windows.h"
#include "stdio.h";
#include "winsock2.h";

#pragma comment(lib,"WS2_32.lib");

int main(int argc, char* argv[])
{
 WORD version;
 WSADATA wsa_data;
 sockaddr_in server_address;
 char *buffer="";

 version=MAKEWORD(2,2);
 server_address.sin_family=AF_INET;
 server_address.sin_port=htons(8888);
 server_address.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");

 ::WSAStartup(version,&wsa_data);
 SOCKET clientSocket=::socket(AF_INET,SOCK_STREAM,0);
 ::connect(clientSocket,(sockaddr*)&server_address,sizeof(server_address));
 ::recv(clientSocket,buffer,sizeof(buffer),0);
 
 printf("接收到数据:%s\n",*buffer);
 ::closesocket(clientSocket);
 ::WSACleanup();


 return 0;
}

这是客户端程序,服务端程序也差不多,就是向客户端发送了一个hello字符串,
但我在客户端却接收不道,接收到后显示是null,如果把char *buffer="";换成
char buffer[256];却可以正确接收到,这是为什么呢?我又是为什么接收不到的呢?

答案:从一个套接口接收数据。
  #include <winsock.h>
  int PASCAL FAR recv( SOCKET s, char FAR* buf, int len, int flags);
  s:一个标识已连接套接口的描述字。
  buf:用于接收数据的缓冲区。
  len:缓冲区长度。
  flags:指定调用方式。
注释:
  本函数用于已连接的数据报或流式套接口s进行数据的接收。
  对SOCK_STREAM类型的套接口来说,本函数将返回所有可用的信息,最大可达缓冲区的大小。如果套接口被设置为线内接收带外数据(选项为SO_OOBINLINE),且有带外数据未读入,则返回带外数据。应用程序可通过调用ioctlsocket()的SOCATMARK命令来确定是否有带外数据待读入。
  对于数据报类套接口,队列中第一个数据报中的数据被解包,但最多不超过缓冲区的大小。如果数据报大于缓冲区,那么缓冲区中只有数据报的前面部分,其他的数据都丢失了,并且recv()函数返回 WSAEMSGSIZE错误。如果没有数据待读,那么除非是非阻塞模式,不然的话套接口将一直等待数据的到来,此时将返回SOCKET_ERROR错误,错误代码是WSAEWOULDBLOCK。用select()或WSAAsynSelect()可以获知何时数据到达。
  如果套接口为SOCK_STREAM类型,并且远端“优雅”地中止了连接,那么recv()一个数据也不读取,立即返回。如果立即被强制中止,那么recv()将以WSAECONNRESET错误失败返回。在套接口的所设选项之上,还可用标志位 flag来影响函数的执行方式。也就是说,本函数的语义既取决于套接口选项,也取决于标志位参数。标志位可取下列值:
  值 意义
  MSG_PEEK查看当前数据。数据将被复制到缓冲区中,但并不从输入队列中删除。
  MSG_OOB 处理带外数据(参见2.2.3节具体讨论)。
  返回值:
  若无错误发生,recv()返回读入的字节数。如果连接已中止,返回0。否则的话,返回SOCKET_ERROR错误,应用程序可通过WSAGetLastError()获取相应错误代码。
  错误代码:
  WSANOTINITIALISED:在使用此API之前应首先成功地调用WSAStartup()。
  WSAENETDOWN:WINDOWS套接口实现检测到网络子系统失效。
  WSAENOTCONN:套接口未连接。
  WSAEINTR:阻塞进程被WSACancelBlockingCall()取消。
  WSAEINPROGRESS:一个阻塞的WINDOWS套接口调用正在运行中。
  WSAENOTSOCK:描述字不是一个套接口。
  WSAEOPNOTSUPP:指定了MSG_OOB,但套接口不是SOCK_STREAM类型的。
  WSAESHUTDOWN:套接口已被关闭。当一个套接口以0或2的how参数调用shutdown()关闭后,无法再用recv()接收数据。
  WSAEWOULDBLOCK:套接口标识为非阻塞模式,但接收操作会产生阻塞。
  WSAEMSGSIZE:数据报太大无法全部装入缓冲区,故被剪切。
  WSAEINVAL:套接口未用bind()进行易做图。
  WSAECONNABORTED:由于超时或其他原因,虚电路失效。
  WSAECONNRESET:远端强制中止了虚电路。


用char *buffer="",缓存区大小是0,当然收不到。
用char buffer[256],缓冲区大小是256,当然可以。

这是明显的对指针不熟悉,“char *buffer”这是定义的一个指针,你并没有给他确定的指向,怎么能就这么用了呢,还好你定义的时候是“char *buffer="";”,如果没有“=""”估计程序直接就崩溃了,这个问题主要就是因为你对指针不熟;要么你再定义一个变量char buffer_tmp[256];buffer=buffer_tmp;然后再用buffer就可以了,要么你就直接用变量buffer_tmp,也就是你上面说的buffer[256];你好好看看指针的用法就知道是哪里的问题了。

上一个:将下面C++代码翻译成Pascal代码
下一个:帮忙注释一段C++程序,谢谢你

CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,