UDP客户端在建立了插口后会直接用sendto函数发送数据,还隐含了一个操作,
那就是在发送数据之前,UDP会首先为该插口选择一个独立的UDP端口(在1024
-5000之间),将该插口置为已绑定状态。如果一个UDP客户端在建立了插口后
首先用bind函数指明了本地地址/端口,也是可以的,这样可以强迫UDP使用指
定的端口发送数据。(事实上,UDP无所谓服务器和客户端,这里的界限已经模
糊了。)
//======================================================
//服务端
#include
#include
#include
#include
#include
#include
#define MAXLINE 80
#define SERV_PORT 502
void do_echo(int sockfd, struct sockaddr *pcliaddr, socklen_t clilen)
{
int n;
socklen_t len;
char mesg[MAXLINE];
for(;;)
{
len = clilen;
/* waiting for receive data */
n = recvfrom(sockfd, mesg, MAXLINE, 0, pcliaddr, &len);
mesg[n-1]=0;
printf("recvfrom data:%s\n",mesg);
/* sent data back to client */
sendto(sockfd, mesg, n, 0, pcliaddr, len);
}
}
int main(void)
{
int sockfd;
struct sockaddr_in servaddr, cliaddr;
sockfd = socket(AF_INET, SOCK_DGRAM, 0); /* create a socket */
/* init servaddr */
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(SERV_PORT);
/* bind address and port to socket */
if(bind(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) == -1)
{
perror("bind error");
exit(1);
}
printf("UPD servese is bind success and do_echo now\n");
do_echo(sockfd, (struct sockaddr *)&cliaddr, sizeof(cliaddr));
return 0;
}
//=============================================
//客户端1 使用本地固定的端口
#include
#include
#include
#include
#include
#include
#include
#include
#define MAXLINE 80
#define SERV_PORT 8888
void do_cli(FILE *fp, int sockfd, struct sockaddr *pservaddr, socklen_t servlen)
{
int n;
char sendline[MAXLINE], recvline[MAXLINE + 1];
/* connect to server */
if(connect(sockfd, (struct sockaddr *)pservaddr, servlen) == -1)
{
perror("connect error");
exit(1);
}
printf("Please input your str want to send:\n");
while(fgets(sendline, MAXLINE, fp) != NULL)
{
/* read a line and send to server */
write(sockfd, sendline, strlen(sendline));
/* receive data from server */
n = read(sockfd, recvline, MAXLINE);
if(n == -1)
{
perror("read error");
exit(1);
}
recvline[n] = 0; /* terminate string */
printf("receive str:\n");
fputs(recvline, stdout);
printf("\n==================================\n");
printf("Please input your str want to send:\n");
}
}
int main(int argc, char **argv)
{
int sockfd;
struct sockaddr_in servaddr;
/* check args */
if(argc != 2)
{
printf("usage: udpclient
exit(1);
}
/* init servaddr */
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(SERV_PORT);
if(inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0)
{
printf("[%s] is not a valid IPaddress\n", argv[1]);
exit(1);
}
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
printf("cli is ready,now do funtion do_cli! \n", argv[1]);
do_cli(stdin, sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
return 0;
}
//==================================
//客户端2 代码 使用随机端口
//http://haibor1x.blog.163.com/blog/static/763407200751052458572/
#include
#include
#include
#include
#include
#include
#include
#include
#define SERV_PORT 502
#define MAXLINE 80
void do_cli(FILE *fp, int sockfd, sockaddr_in toAddr)
{
int n;
struct sockaddr_in fromAddr;
char sendline[MAXLINE], recvline[MAXLINE + 1];
printf("Please input your str want to send:\n");
while(fgets(sendline, MAXLINE, fp) != NULL)
{
/* read a line and send to server */
//write(sockfd, sendline, strlen(sendline));
if(sendto(sockfd,sendline,strlen(sendline),0,
(struct sockaddr*)&toAddr,sizeof(toAddr)) !=
strlen(sendline))
{
printf("sendto() 函数使用失败了.\r\n");
close(sockfd);
exit(1);
}
printf("wait for data ...\n");
/* receive data from server */
//n = read(sockfd, recvline, MAXLINE);
unsigned int fromLen = sizeof(fromAddr);
if(recvfrom(sockfd,recvline,MAXLINE,0,
(struct sockaddr*)&fromAddr,&fromLen)<0)
{
printf(" ()recvfrom()函数使用失败了.\r\n");
close(sockfd);
exit(1);
}
else{
printf("get nothing data ...\n");
}
recvline[strlen(sendline)-1] = 0;
printf("receive str:\n");
fputs(recvline, stdout);
printf("\n==================================\n");
printf("Please input your str want to send:\n");
}
}
int main(int argc, char *argv[])
{
int sock;
//sendto中使用的对方地址
struct sockaddr_in toAddr;
//在recvfrom中使用的对方主机地址
struct sockaddr_in fromAddr;
sock = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
if(sock < 0)
{
printf(" 创建套接字失败了.\r\n");
exit(1);
}
memset(&toAddr,0,sizeof(toAddr));
toAddr.sin_family=AF_INET;
toAddr.sin_addr.s_addr=inet_addr("192.168.0.110");
toAddr.sin_port = htons(SERV_PORT);
do_cli(stdin, sock, toAddr);
close(sock);
return 0;
}