请问socket 的send 和recv ,只能发送和接收字符数组吗?

socket只能发送和接收字符数组吗?而若先告诉要发多少字节,字符数组缺好像不能按变量长度声明。。。

我是初学windows环境的简单socket,而其实老师要求是Unix下学精。。请知道的朋友不吝赐教~~~ 这个问题困扰很久了。。。

第1个回答  推荐于2016-05-21
Windows:

1.简单服务器
//#include <winsock2.h>
//#pragma comment(lib,"WS2_32.lib")
WSADATA wsd;
static UINT port=%%1;
UINT Listen(LPVOID pParam)
{
SOCKET sServer,sClient;
char buf[1024];
int retVal;
if(WSAStartup(MAKEWORD(2,2),&wsd)!=0)
{
return -1;//失败
}
sServer=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(INVALID_SOCKET==sServer)
{
WSACleanup();
return -1;//创建套接字失败
}
SOCKADDR_IN addrServ;
addrServ.sin_family=AF_INET;
addrServ.sin_port=htons((short)pParam);
addrServ.sin_addr.s_addr=INADDR_ANY;
retVal=bind(sServer,(LPSOCKADDR)&addrServ,sizeof(SOCKADDR_IN));
if(SOCKET_ERROR==retVal)
{
closesocket(sServer);
WSACleanup();
return -1;//绑定套接字失败
}
retVal=listen(sServer,1);
if(SOCKET_ERROR==retVal)
{
closesocket(sServer);
WSACleanup();
return -1;//开始监听失败
}
sockaddr_in addrClient;
int addrClientlen=sizeof(addrClient);
sClient=accept(sServer,(sockaddr FAR*)&addrClient,&addrClientlen);
if(INVALID_SOCKET==sClient)
{
closesocket(sServer);
WSACleanup();
return -1;//开始接受客户端连接失败
}
ZeroMemory(buf,sizeof(buf));
retVal=recv(sClient,buf,sizeof(buf),0);
if(SOCKET_ERROR==retVal)
{
closesocket(sServer);
closesocket(sClient);
WSACleanup();
return -1;//接收数据失败
}
CString %%2(buf);
closesocket(sServer);
closesocket(sClient);
WSACleanup();
return 0;
}
CWinThread *pThread=AfxBeginThread(Listen,&port);

2.简单客户端
//#include <winsock2.h>
//#pragma comment(lib,"WS2_32.lib")
WSADATA wsd;
SOCKET sHost;
SOCKADDR_IN servAddr;
char buf[1024];
int retVal;
if(WSAStartup(MAKEWORD(2,2),&wsd)!=0)
{
return -1;//失败
}
sHost=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(INVALID_SOCKET==sHost)
{
WSACleanup();
return -1;//创建套接字失败
}
servAddr.sin_family=AF_INET;
servAddr.sin_addr.s_addr=inet_addr(%%3);
servAddr.sin_port=htons((short)%%2);
int nServAddlen=sizeof(servAddr);
retVal=connect(sHost,(LPSOCKADDR)&servAddr,sizeof(servAddr));
if(SOCKET_ERROR==retVal) {
closesocket(sHost);
WSACleanup();
return -1;//连接服务器失败
}
ZeroMemory(buf,sizeof(buf));
strcpy(buf,%%3);
retVal=send(sHost,buf,sizeof(buf),0);
if(SOCKET_ERROR==retVal)
{
closesocket(sHost);
WSACleanup();
return -1;//向服务器发送数据失败
}
closesocket(sHost);
WSACleanup();

3.获得本机IP
//#include <winsock2.h>
//#pragma comment(lib,"WS2_32.lib")
WSADATA wsd;
if(WSAStartup(MAKEWORD(2,2),&wsd)!=0)
{
return -1;//失败
}
char szHostname[100],szHostaddress[200];
if(gethostname(szHostname,sizeof(szHostname))!=SOCKET_ERROR)
{
HOSTENT *pHostEnt=gethostbyname(szHostname);
if(pHostEnt!=NULL){
sprintf(szHostaddress,"%d.%d.%d.%d",
( pHostEnt->h_addr_list[0][0]&0x00ff ),
( pHostEnt->h_addr_list[0][1]&0x00ff ),
( pHostEnt->h_addr_list[0][2]&0x00ff ),
( pHostEnt->h_addr_list[0][3]&0x00ff ));
}
}
else
return;
CString %%1(szHostaddress);

Unix:
1.简单客户端

/*
#include
#include
#include
#include
#include
#include
#include
#include

int main(int argc, char *argv[])
{
int sockfd;
char buffer[1024];
struct sockaddr_in server_addr;
struct hostent *host;
int portnumber,nbytes;

if(argc!=3)
{
fprintf(stderr,"Usage:%s hostname portnumber\a\n",argv[0]);
exit(1);
}

if((host=gethostbyname(argv[1]))==NULL)
{
fprintf(stderr,"Gethostname error\n");
exit(1);
}

if((portnumber=atoi(argv[2]))?0)
{
fprintf(stderr,"Usage:%s hostname portnumber\a\n",argv[0]);
exit(1);
}

/* 客户程序开始建立 sockfd描述符 */
if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)
{
fprintf(stderr,"Socket Error:%s\a\n",strerror(errno));
exit(1);
}

/* 客户程序填充服务端的资料 */
bzero(&server_addr,sizeof(server_addr));
server_addr.sin_family=AF_INET;
server_addr.sin_port=htons(portnumber);
server_addr.sin_addr=*((struct in_addr *)host-?h_addr);

/* 客户程序发起连接请求 */
if(connect(sockfd,(struct sockaddr *)(&server_addr),sizeof(struct sockaddr))==-1)
{
fprintf(stderr,"Connect Error:%s\a\n",strerror(errno));
exit(1);
}

/* 连接成功了 */
if((nbytes=read(sockfd,buffer,1024))==-1)
{
fprintf(stderr,"Read Error:%s\n",strerror(errno));
exit(1);
}
buffer[nbytes]=’\0′;
printf("I have received:%s\n",buffer);
/* 结束通讯 */
close(sockfd);
exit(0);
}

*/
int sock_connect(char *domain,int port)
{
int white_sock;
struct hostent * site;
struct sockaddr_in me;
site = gethostbyname(domain);
if (site==NULL) return -2;

white_sock = socket(AF_INET,SOCK_STREAM,0);
if (white_sock?0) return -1;

memset(&me,0,sizeof(struct sockaddr_in));
memcpy(&me.sin_addr,site-?h_addr_list[0],site-?h_length);
me.sin_family = AF_INET;
me.sin_port = htons(port);

return (connect(white_sock,(struct sockaddr *)&me,sizeof(struct sockaddr))?0) ? -1 : white_sock;
}

2.简单服务器端

/*
服务器端程序

/******* 服务器程序 (server.c) ************/
#include
#include
#include
#include
#include
#include
#include
#include

int main(int argc, char *argv[])
{
int sockfd,new_fd;
struct sockaddr_in server_addr;
struct sockaddr_in client_addr;
int sin_size,portnumber;
char hello[]="Hello! Are You Fine?\n";

if(argc!=2)
{
fprintf(stderr,"Usage:%s portnumber\a\n",argv[0]);
exit(1);
}

if((portnumber=atoi(argv[1]))?0)
{
fprintf(stderr,"Usage:%s portnumber\a\n",argv[0]);
exit(1);
}

/* 服务器端开始建立socket描述符 */
if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)
{
fprintf(stderr,"Socket error:%s\n\a",strerror(errno));
exit(1);
}

/* 服务器端填充 sockaddr结构 */
bzero(&server_addr,sizeof(struct sockaddr_in));
server_addr.sin_family=AF_INET;
server_addr.sin_addr.s_addr=htonl(INADDR_ANY);
server_addr.sin_port=htons(portnumber);

/* 捆绑sockfd描述符 */
if(bind(sockfd,(struct sockaddr *)(&server_addr),sizeof(struct sockaddr))==-1)
{
fprintf(stderr,"Bind error:%s\n\a",strerror(errno));
exit(1);
}

/* 监听sockfd描述符 */
if(listen(sockfd,5)==-1)
{
fprintf(stderr,"Listen error:%s\n\a",strerror(errno));
exit(1);
}

while(1)
{
/* 服务器阻塞,直到客户程序建立连接 */
sin_size=sizeof(struct sockaddr_in);
if((new_fd=accept(sockfd,(struct sockaddr *)(&client_addr),&sin_size))==-1)
{
fprintf(stderr,"Accept error:%s\n\a",strerror(errno));
exit(1);
}

fprintf(stderr,"Server get connection from %s\n",
inet_ntoa(client_addr.sin_addr));
if(write(new_fd,hello,strlen(hello))==-1)
{
fprintf(stderr,"Write Error:%s\n",strerror(errno));
exit(1);
}
/* 这个通讯已经结束 */
close(new_fd);
/* 循环下一个 */
}
close(sockfd);
exit(0);
}

客户端程序

*/
int DaemonSocket;
struct sockaddr_in DaemonAddr;
int BindSocket(void)
{
DaemonSocket = socket(AF_INET,SOCK_STREAM,0);
if (DaemonSocket==-1) return 0;
DaemonAddr.sin_family = AF_INET;
DaemonAddr.sin_port = htons(DAEMON_PORT);
if (bind(DaemonSocket,&DaemonAddr,sizeof(DaemonAddr))?0) {
printf("Can not bind!\n");
return 0;
}
if (listen(DaemonSocket,1024)!=0) {
printf("Can not listen!\n");
return 0;
}
return 1;
}

//要查看是否有连线进来,可用以下方式:
int incoming_call(void)
{
fd_set sock;
struct timeval tv;
int t;

FD_ZERO(&sock);
FD_SET(DaemonSocket,&sock);
tv.tv_sec = 60; tv.tv_usec = 0;
t = select(DaemonSocket + 1,&sock,NULL,NULL,&tv);
if (t?=0||!FD_ISSET(DaemonSocket,&sock)) return 0;

printf("incoming…\n");

return 1;
}

//Connect Client
//当我们确认有人进来要求服务时,会需要accept connection,可用以下方式
int ConnectClient(void)
{
int socksize=sizeof(HostAddr);
unsigned char * addr;

ClientSocket = accept(DaemonSocket,(struct sockaddr*)&HostAddr,&socksize);
if (ClientSocket?0) return 0;

addr = (unsigned char *)&HostAddr.sin_addr.s_addr;

printf("incoming address:%d.%d.%d.%d\n",addr[0],addr[1],addr[2],addr[3]);

return 1;
}本回答被提问者采纳
第2个回答  2009-07-17
看看我的blog去,linux环境下的

http://blog.chinaunix.net/u3/93784/
第3个回答  2009-07-10
没看懂

请问socket 的send 和recv ,只能发送和接收字符数组吗?
而若先告诉要发多少字节,字符数组缺好像不能按变量长度声明。。。我是初学windows环境的简单socket,而其实老师要求是Unix下学精。。请知道的朋友不... socket只能发送和接收字符数组吗?而若先告诉要发多少字节,字符数组缺好像不能按变量长度声明。。。我是初学windows环境的简单socket,而其实老师要求是Unix下学精。。

Socket send函数和recv函数详解
对于异步Socket的send函数,在网络刚断开时仍能发送,并返回相应字节数,select检测也是可写的,但稍后再次发送会出错。select检测无法检测出可写状态。recv函数 recv函数用于从TCP连接另一端接收数据。客户端和服务器应用程序都可使用此函数。函数接收套接字描述符、接收数据缓冲区、数据长度及标志参数。执行...

socket编程·send和recv
socket的send和recv是同时支持TCP和UDP的。从这两个函数的设计可以看出,协议简单来说就是读写数据。socket的选项是 SOCK_STREAM 。 send的返回值>0时,表示实际发送了多少字节。 注意: 只是copy到系统缓存里,系统决定什么时候会发送这些数据。 send的返回值==0时,这个在send空串时会发生,是...

send与recv函数详解
总的来说,send和recv函数分别负责在socket通信中提交和接收数据,涉及发送缓冲区和接收缓冲区的管理,以及协议层面的数据传输控制。

C++ Socket send recv 循环发送和接收 阻塞与缓冲区
send函数负责将数据写入输出缓冲区,数据发送到目标主机由TCP协议完成。recv函数从输入缓冲区读取数据,数据接收是独立的,recv函数不会判断数据包结束位置。数据的发送和接收不是一次完成,可能存在数据堆积在缓冲区中等待接收的情况。循环发送与接收 确保数据完整传输的关键是正确管理套接字的缓冲区。在循环...

TCP协议之Send和Recv原理及常见问题分析
recv函数的执行流程是等待s的发送缓冲中的数据被协议传送完毕。如果协议在传送s的发送缓冲中的数据时出现网络错误,则recv函数返回SOCKET_ERROR。如果s的发送缓冲中没有数据或数据被协议成功发送完毕,则recv函数先检查套接字s的接收缓冲区。如果s接收缓冲区中没有数据或协议正在接收数据,则recv函数就一直等待,直到协议...

TCP之深入浅出send&recv
recv函数实现类似,从数据链路层接收数据帧,通过网卡驱动处理后,进入内核进行协议层处理,最终将数据放入socket的接收缓冲区。在实际应用中,非阻塞send时,发送端可能发送了大量数据,但实际只发送了部分,缓冲区中仍有大量数据未发送。接收端recv获取数据时,可能只收到部分数据。这种情况下,应用层需要...

recv\/send\/recvfrom\/sendto\/recvmsg\/sendmsg小结
使用read和write函数也可进行网络套接字读写,写入后数据暂存于内核TCP发送缓冲区,具体传输、接收及处理无保障。write函数阻塞发生在内核socket发送缓冲区满时,每个socket拥有独立的接收与发送缓冲区。在TCP上下文中,通常使用recv和send函数,send函数接收sockfd上的数据,buf和len参数指定位置和大小,成功...

在socket编程中怎么判断recv是否接收完成
client的发函数为:char line[MAXLINE]; while ((fgets(line,MAXLINE,fd)!=NULL) \/\/ fd 为一个文件的指针 {send (connfd, line,strlen(line),0) \/\/ connfd为 socket}server 的接收函数为:for (;;) {if ((n=recv(connfd, recvline,MAXLINE,0)>0) {recvline[n]=0;fputs(stdout,...

socket中的receive、send函数
这个不难,bytes = temp.Receive(recvBytes, recvBytes.Length, 0);是说接收长度为recvBytes.Length的数据并将数据放进recvBytes中。bytes表示通过套接字一次接收的数据长度。temp.Send(bs, bs.Length, 0);是说发送长度为bs.Length的bs中的数据。参数0表示指定的传输控制方式,0就表示没有特殊行为。

相似回答