一.
1. 流程描述
udp的demo既有server端又有client端,两者互相通信
client --> sendto --> recvfrom
server--> recvfrom --> sendto
2. 代码
2.1 client.c
-
cong@msi:/work/test/tcpip/14udp/client$ cat client.c
-
#include "utils.h"
-
-
//#define TIME_SERV_ADDR "192.168.4.98"
-
#define TIME_SERV_ADDR "127.0.0.1"
-
-
void dg_cli(FILE* fp, int sockfd, const struct sockaddr* pservaddr, socklen_t servlen)
-
{
-
int n;
-
char sendline[MAXLINE], recvline[MAXLINE];
-
while(fgets(sendline, MAXLINE, fp) != NULL)
-
{
-
//write(sockfd, sendline, strlen(sendline));
-
//这儿的pservaddr一定要初始化,要不client就不知道要发给谁了
-
sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen); //a.sendto发送到服务器
-
//这儿的第5个参数设为NULL,因为client不需要知道是谁发给它的,所以书上说这儿有个bug
-
n = recvfrom(sockfd, recvline, MAXLINE, 0, NULL, NULL); //d.recvfrom接收服务器的数据
-
recvline[n] = 0;
-
fputs(recvline, stdout);
-
}
-
}
-
-
int main ( int argc, char *argv[] )
-
{
-
int sockfd, n;
-
struct sockaddr_in servaddr;
-
char recvline[1024];
-
//sockfd = socket(AF_INET, SOCK_STREAM, 0);
-
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
-
if(sockfd < 0)
-
return -1;
-
bzero(&servaddr, sizeof(servaddr));
-
servaddr.sin_family = AF_INET;
-
servaddr.sin_port = htons(13999);
-
inet_pton(AF_INET, TIME_SERV_ADDR, &servaddr.sin_addr);
-
-
//connect(sockfd, (const struct sockaddr*)&servaddr, sizeof(servaddr));
-
dbmsg("next dg_cli");
-
dg_cli(stdin, sockfd, (const struct sockaddr*)&servaddr, sizeof(servaddr));
-
return EXIT_SUCCESS;
-
}
2.2 serv.c
-
cong@msi:/work/test/tcpip/14udp/serv$ cat udpserv.c
-
#include "utils.h"
-
-
void dg_echo(int sockfd, struct sockaddr* pcliaddr, socklen_t clilen)
-
{
-
int n;
-
socklen_t len;
-
char mesg[MAXLINE];
-
while(1)
-
{
-
len = clilen;
-
//recvfrom把client的端口号与地址保存在pcliaddr中
-
n = recvfrom(sockfd, mesg, MAXLINE, 0, pcliaddr, &len); //b.recvfrom收到client的数据
-
//因为recvfrom己保存了client的端口与地址,所以serv就知道该发到哪儿去了,这就是pcliaddr的作用
-
sendto(sockfd, mesg, n, 0, pcliaddr, len); //c.sendto发送到client
-
}
-
}
-
-
int main ( int argc, char *argv[] )
-
{
-
int sockfd, connfd;
-
struct sockaddr_in servaddr, cliaddr;
-
pid_t childpid;
-
char buf[1024];
-
int len;
-
//sockfd = socket(AF_INET, SOCK_STREAM, 0);
-
sockfd = socket(AF_INET, SOCK_DGRAM, 0); //由SOCK_STREAM改为SOCK_DGRAM
-
if(sockfd < 0)
-
return -1;
-
bzero(&servaddr, sizeof(servaddr));
-
servaddr.sin_family = AF_INET;
-
servaddr.sin_port = htons(13999);
-
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
-
//inet_pton(AF_INET, TIME_SERV_ADDR, &servaddr.sin_addr);
-
-
bind(sockfd, (const struct sockaddr*)&servaddr, sizeof(servaddr)); //bind就行了没有listen
-
dg_echo(sockfd, (struct sockaddr*)&cliaddr, sizeof(cliaddr));
-
-
return EXIT_SUCCESS;
-
}
这儿打印了pcliaddr
-
在内核的include/linux/socket.h中
-
struct sockaddr {
-
sa_family_t sa_family; /* address family, AF_xxx */
-
char sa_data[14]; /* 14 bytes of protocol address */
-
};
-
-
所以打印如下:
-
for(i=0; i<14; i++)
-
dbmsg("%d= 0x%x",i, (unsigned char)pcliaddr->sa_data[i]);
-
-
udpserv.c:dg_echo[16]: 0= 0xb5
-
udpserv.c:dg_echo[16]: 1= 0xba
-
udpserv.c:dg_echo[16]: 2= 0x7f
-
udpserv.c:dg_echo[16]: 3= 0x0
-
udpserv.c:dg_echo[16]: 4= 0x0
-
udpserv.c:dg_echo[16]: 5= 0x1
-
udpserv.c:dg_echo[16]: 6= 0x0
-
udpserv.c:dg_echo[16]: 7= 0x0
-
udpserv.c:dg_echo[16]: 8= 0x0
-
udpserv.c:dg_echo[16]: 9= 0x0
-
udpserv.c:dg_echo[16]: 10= 0x0
-
udpserv.c:dg_echo[16]: 11= 0x0
-
udpserv.c:dg_echo[16]: 12= 0x0
-
udpserv.c:dg_echo[16]: 13= 0x0
-
其中 0xb5 0xba = b5ba=46522 --> client的端口号
-
7f 00 00 01--> 127.0.0.1 --> client的地址
2.3
client.rar (下载后改名为client.tar.gz)
serv.rar (下载后改名为serv.tar.gz)
二. 修改版
1. clinet.c
-
cong@msi:/work/test/tcpip/16udp/client$ cat udpclient.c
-
#include "utils.h"
-
#include <unistd.h>
-
#include <sys/time.h>
-
#include <stdlib.h>
-
-
//#define TIME_SERV_ADDR "192.168.4.98"
-
#define TIME_SERV_ADDR "127.0.0.1"
-
-
long int get_now_us_time()
-
{
-
struct timeval start;
-
long int now_time;
-
gettimeofday(&start, NULL);
-
now_time = start.tv_sec*1000+ start.tv_usec/1000;
-
return now_time;
-
}
-
-
-
void dg_cli(FILE* fp, int sockfd, const struct sockaddr* pservaddr, socklen_t servlen)
-
{
-
int n, i,j;
-
long int t1,t2;
-
char sendline[MAXLINE], recvline[MAXLINE];
-
//while(fgets(sendline, MAXLINE, fp) != NULL)
-
//while(1)
-
for(j=0; j<3; j++)
-
{
-
memset(sendline, 0, sizeof(sendline));
-
for(i=0; i<64; i++)
-
{
-
sendline[i] = i;
-
}
-
t1 = get_now_us_time();
-
//write(sockfd, sendline, strlen(sendline));
-
sendto(sockfd, sendline, 64, 0, pservaddr, servlen);
-
-
n = recvfrom(sockfd, recvline, MAXLINE, 0, NULL, NULL);
-
t2 = get_now_us_time();
-
printf("time=%ld\n", t2-t1);
-
recvline[n] = 0;
-
fputs(recvline, stdout);
-
sleep(1);
-
}
-
-
}
-
-
int main ( int argc, char *argv[] )
-
{
-
int sockfd, n;
-
struct sockaddr_in servaddr;
-
char recvline[1024];
-
//sockfd = socket(AF_INET, SOCK_STREAM, 0);
-
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
-
if(sockfd < 0)
-
return -1;
-
bzero(&servaddr, sizeof(servaddr));
-
servaddr.sin_family = AF_INET;
-
servaddr.sin_port = htons(9000);
-
inet_pton(AF_INET, TIME_SERV_ADDR, &servaddr.sin_addr);
-
-
//connect(sockfd, (const struct sockaddr*)&servaddr, sizeof(servaddr));
-
dbmsg("next dg_cli");
-
dg_cli(stdin, sockfd, (const struct sockaddr*)&servaddr, sizeof(servaddr));
-
return EXIT_SUCCESS;
-
}
2.server
-
cong@msi:/work/test/tcpip/16udp/serv$ cat udpserv.c
-
#include "utils.h"
-
-
char * sock_ntop(const struct sockaddr *sa, socklen_t salen)
-
{
-
char portstr[8];
-
static char str[128]; /* Unix domain is largest */
-
struct sockaddr_in *sin = (struct sockaddr_in *) sa;
-
//only process AF_INET
-
if (inet_ntop(AF_INET, &sin->sin_addr, str, sizeof(str)) == NULL)
-
return(NULL);
-
if (ntohs(sin->sin_port) != 0) {
-
snprintf(portstr, sizeof(portstr), ":%d", ntohs(sin->sin_port));
-
strcat(str, portstr);
-
}
-
return(str);
-
}
-
-
void dg_echo(int sockfd, struct sockaddr* pcliaddr, socklen_t clilen)
-
{
-
int n;
-
int i;
-
socklen_t len;
-
char mesg[MAXLINE];
-
while(1)
-
{
-
len = clilen;
-
#if 0
-
for(i=0; i<14; i++)
-
dbmsg("%d= 0x%x",i, (unsigned char)pcliaddr->sa_data[i]);
-
#endif
-
n = recvfrom(sockfd, mesg, MAXLINE, 0, pcliaddr, &len);
-
dbmsg("n=%d, len=%d", n, len);
-
for(i=0; i<n; i++)
-
printf("%d=0x%x ",i, mesg[i]);
-
printf("\n");
-
sendto(sockfd, mesg, n, 0, pcliaddr, len);
-
}
-
}
-
-
int main ( int argc, char *argv[] )
-
{
-
int sockfd, connfd;
-
struct sockaddr_in servaddr, cliaddr;
-
pid_t childpid;
-
char buf[1024];
-
int len;
-
//sockfd = socket(AF_INET, SOCK_STREAM, 0);
-
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
-
if(sockfd < 0)
-
return -1;
-
bzero(&servaddr, sizeof(servaddr));
-
servaddr.sin_family = AF_INET;
-
servaddr.sin_port = htons(9000);
-
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
-
//inet_pton(AF_INET, TIME_SERV_ADDR, &servaddr.sin_addr);
-
-
bind(sockfd, (const struct sockaddr*)&servaddr, sizeof(servaddr));
-
dg_echo(sockfd, (struct sockaddr*)&cliaddr, sizeof(cliaddr));
-
-
return EXIT_SUCCESS;
-
}
2.3
client.rar(下载后改名为client.tar.gz)
serv.rar(下载后改名为serv.tar.gz)
阅读(1232) | 评论(0) | 转发(0) |