如何用udp发送和接受?
我在本机运行下面两个程序,一个是client,负责向server发送数据
一个是server,负责接收client发送过来的数据,但是不能成功,请大家告诉我一个标准的udp连接应该怎么写,谢谢
//program1
//udp client
#include<winsock.h>
#include<memory.h>
#include<iostream.h>
#include<stdio.h>
void main()
{
SOCKADDR_IN client_addr;
SOCKADDR_IN server_addr;
SOCKET sock;
char buff[1024]={0};
//WSAstartup()
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 1, 1 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 )
{
return;
}
if ( LOBYTE( wsaData.wVersion ) != 1 ||
HIBYTE( wsaData.wVersion ) != 1 )
{
WSACleanup( );
return;
}
memset( &client_addr, 0, sizeof(client_addr) );
client_addr.sin_family=AF_INET;
client_addr.sin_port=1313;
int length=sizeof(client_addr);
memset( &server_addr, 0, sizeof(server_addr) );
struct hostent *hp;
hp=gethostbyname("localhost");
if(hp==0)
{
int temp_error=WSAGetLastError();
cout<<"unknow host"<<endl;
exit(2);
}
memcpy((char*)&server_addr.sin_addr,(char*)hp->h_addr,hp->h_length);
server_addr.sin_port=htons(atoi("1300"));
int server_length=sizeof(server_addr);
/* const char *server_ip="192.168.1.1";
server_addr.sin_addr.s_addr = inet_addr(server_ip);
int len=sizeof(server_addr);
*/
int temp_error;//暂存WSAGetLastError返回值
if((sock=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP))<0)
{
temp_error=WSAGetLastError();
cout<<"creat socket error"<<temp_error<<endl;
closesocket(sock);
WSACleanup();
}
if((bind(sock,(LPSOCKADDR)(&client_addr),length))!=0)
{
temp_error=WSAGetLastError();
cout<<"bind error"<<temp_error<<endl;
closesocket(sock);
WSACleanup();
}
cout<<"socket port#"<<ntohs(client_addr.sin_port)<<endl;
int i=0;int j=0;
char alpher[27]={'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','\0'};
for(i=0;i<1023;i++)
{
j=i-int(i/26)*26;
buff[i]=alpher[j];
}
buff[1023]='\0';
do
{
sendto(sock,buff,1024*sizeof(char),MSG_DONTROUTE,(struct sockaddr*)(&server_addr),sizeof(server_addr));
recvfrom(sock,buff,sizeof(char)*1024,MSG_DONTROUTE,(struct sockaddr*)(&server_addr),&server_length);
}while(1);
}
//program2
//udpserver
#include<winsock.h>
#include<memory.h>
#include<iostream.h>
#include<stdio.h>
void main()
{
SOCKADDR_IN server_addr;
SOCKADDR_IN client_addr;
SOCKET sock;
char buff[1024]={0};
//WSAstartup()
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 1, 1 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 )
{
return;
}
if ( LOBYTE( wsaData.wVersion ) != 1 ||
HIBYTE( wsaData.wVersion ) != 1 )
{
WSACleanup( );
return;
}
memset( &server_addr, 0, sizeof(server_addr) );
int length=sizeof(server_addr);
server_addr.sin_family=AF_INET;
server_addr.sin_port=1300;
memset( &client_addr, 0, sizeof(client_addr) );
int len=sizeof(client_addr);
int temp_error;
if((sock=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP))<0)
{
temp_error=WSAGetLastError();
cout<<"creat socket error"<<temp_error<<endl;
closesocket(sock);
WSACleanup();
}
if(bind(sock,(LPSOCKADDR)(&server_addr),length)!=0)
{
temp_error=WSAGetLastError();
cout<<"bind error"<<temp_error<<endl;
closesocket(sock);
WSACleanup();
}
cout<<"socket port#"<<ntohs(server_addr.sin_port)<<endl;
recvfrom(sock,buff,sizeof(char)*1024,MSG_DONTROUTE,(struct sockaddr*)(&client_addr),&len);
cout<<buff<<endl;
}
问题点数:20、回复次数:10Top
1 楼superdreamer(只懂一点点!)回复于 2001-11-30 09:00:50 得分 0
哈哈,你的程序肯定不能发送啦,你的两个都写成服务器端,没有客户端啊
标准的格式如下:
server: socket->bind->recvfrom
client: socket->connect->sendtoTop
2 楼nm_csdn_0()回复于 2001-11-30 10:51:00 得分 0
不是的
,我写的是udp的程序,是非面向连接的,所以在客户端必须要绑定,而且不用connect
你写的模式是面向连接的
:(Top
3 楼superdreamer(只懂一点点!)回复于 2001-11-30 11:00:46 得分 0
UDP客户端可以连接,但连接后就可以用send or recv 发送或接收
UDP在客户端要BIND我还是第一次听说,我上面是写错了,若客户端不用CONNECT 在SOCKET创建后,直接用SENDTO 就可以发送信息了
server:socket->bind-> revcfrom (sendto)
client:socket->sendto(recvfrom)or socket->connect->send(recv)
你的明白!
Top
4 楼nm_csdn_0()回复于 2001-11-30 11:13:21 得分 0
那你说我得程序是错在哪里呀?
希望你给我贴一个能用的简单程序,客户端的和服务器端的Top
5 楼superdreamer(只懂一点点!)回复于 2001-11-30 12:06:38 得分 15
我是在LINUX下写的,你把他移值到WINDOWS下就可以了
server.c
//////////////
#include <stdio.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <unistd.h>
#include <arpa/inet.h>
int main()
{
int server_fd;
int length;
int len;
char buff[128];
struct sockaddr_in server_addr;
struct sockaddr_in client_addr;
server_fd=socket(AF_INET,SOCK_DGRAM,0);
server_addr.sin_family=AF_INET;
server_addr.sin_port=htons(4000);
server_addr.sin_addr.s_addr=htonl(INADDR_ANY);
bind(server_fd,(struct sockaddr *)&server_addr,sizeof(server_addr));
len=sizeof(struct sockaddr_in);
while(1)
{
length=recvfrom(server_fd,buff,strlen(buff),0,(struct sockaddr *)&client_addr,&len);
if(length==-1){
printf("recvfrom error.\n");
break;
}
if(length==0)
break;
buff[length]='\0';
printf("recv data:%s\n",buff);
}
close(server_fd);
return 0;
}
///////////////
client.c
/////////////
#include <sys/wait.h>
#include <unistd.h>
#include <arpa/inet.h>
int main()
{
int client_fd,length;
char buff[]="this is a test!";
struct sockaddr_in server_addr;
client_fd=socket(AF_INET,SOCK_DGRAM,0);
server_addr.sin_family=AF_INET;
server_addr.sin_port=htons(4000);
server_addr.sin_addr.s_addr=inet_addr("127.0.0.1");
length=sendto(client_fd,buff,strlen(buff),0,(struct sockaddr *)&server_addr,sizeof(server_addr));
close(client_fd);
return 0;
}Top
6 楼nm_csdn_0()回复于 2001-11-30 14:28:48 得分 0
我已经按你的程序做了移植,可以连接了,但是
server端用recvfrom()收到数据后返回错误
WSAEMSGSIZE Field
msdn上的解释为
A message sent on a datagram socket was larger than the internal message buffer or some other network limit, or the buffer used to receive a datagram was smaller than the datagram itself.
这是什么意思?
我移植后的代码如下:
//udp client
#include<winsock.h>
#include<memory.h>
#include<iostream.h>
#include<stdio.h>
#include<string.h>
void main()
{
SOCKADDR_IN server_addr;
SOCKET sock;
char buff[1024]="udp";
//WSAstartup()
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 1, 1 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 )
{
return;
}
if ( LOBYTE( wsaData.wVersion ) != 1 ||
HIBYTE( wsaData.wVersion ) != 1 )
{
WSACleanup( );
return;
}
memset( &server_addr, 0, sizeof(server_addr) );
server_addr.sin_family=AF_INET;
server_addr.sin_port=htons(4001);
server_addr.sin_addr.s_addr=inet_addr("192.168.1.111");
int temp_error;//暂存WSAGetLastError返回值
if((sock=socket(AF_INET,SOCK_DGRAM,0))<0)
{
temp_error=WSAGetLastError();
cout<<"creat socket error"<<temp_error<<endl;
closesocket(sock);
WSACleanup();
}
sendto(sock,buff,strlen(buff),0,(struct sockaddr*)(&server_addr),sizeof(server_addr));
closesocket(sock);
WSACleanup();
}
//udpserver
#include<winsock.h>
#include<memory.h>
#include<iostream.h>
#include<stdio.h>
void main()
{
SOCKADDR_IN server_addr;
SOCKADDR_IN client_addr;
SOCKET server_sock;
char buff[1024]={0};
//WSAstartup()
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 1, 1 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 )
{
return;
}
if ( LOBYTE( wsaData.wVersion ) != 1 ||
HIBYTE( wsaData.wVersion ) != 1 )
{
WSACleanup( );
return;
}
memset( &server_addr, 0, sizeof(server_addr) );
int length=sizeof(server_addr);
server_addr.sin_family=AF_INET;
server_addr.sin_port=htons(4001);
server_addr.sin_addr.s_addr=htonl(INADDR_ANY);
memset( &client_addr, 0, sizeof(client_addr) );
int len=sizeof(struct sockaddr_in);
int temp_error;
if((server_sock=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP))<0)
{
temp_error=WSAGetLastError();
cout<<"creat socket error"<<temp_error<<endl;
closesocket(server_sock);
WSACleanup();
}
if(bind(server_sock,(LPSOCKADDR)(&server_addr),length)!=0)
{
temp_error=WSAGetLastError();
cout<<"bind error"<<temp_error<<endl;
closesocket(server_sock);
WSACleanup();
}
cout<<"socket port#"<<ntohs(server_addr.sin_port)<<endl;
//
int string_len;
while(1)
{
string_len=recvfrom(server_sock,buff,strlen(buff),0,(struct sockaddr *)&client_addr,&len);
if(string_len==-1)
{
temp_error=WSAGetLastError();
cout<<"recvfrom error."<<endl;
break;
}
if(string_len==0)
break;
buff[string_len]='\0';
cout<<"recv data:"<<buff<<endl;
}
closesocket(server_sock);
WSACleanup();
}
Top
7 楼zb_china(于是开始苏鲁之的堕落)回复于 2001-11-30 14:56:40 得分 5
回复人: nm_csdn_0() (2001-11-30 14:28:49) 得0分
我已经按你的程序做了移植,可以连接了,但是
server端用recvfrom()收到数据后返回错误
WSAEMSGSIZE Field
msdn上的解释为
A message sent on a datagram socket was larger than the internal message buffer or some other network limit, or the buffer used to receive a datagram was smaller than the datagram itself.
:
要发送的数据报长度太长或者提供的接收缓冲区太短
试试2048,一般最大长度是1500Top
8 楼nm_csdn_0()回复于 2001-11-30 15:24:08 得分 0
我知道了
recvfrom(server_sock,buff,strlen(buff),0,(struct sockaddr *)&client_addr,&len);
应该改为
recvfrom(server_sock,buff,256,0,(struct sockaddr *)&client_addr,&len);
其中256为buff的实际长度
非常感谢的大家对我的帮助Top
9 楼superdreamer(只懂一点点!)回复于 2001-11-30 15:30:04 得分 0
哈哈,你的接受缓冲区char buff[1024]={0};有错
这样strlen(buff)=1,所以出错,记住,接收缓冲区最好不要初始化Top
10 楼superdreamer(只懂一点点!)回复于 2001-12-20 09:22:08 得分 0
TO nm_csdn_0() 不好意思,以前我没有用过UDP,今天我看了资料,我上面的回答有错误,如果服务器和客户端都要互相发送数据,两方都要绑定,再次表示抱歉!Top




