博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
socket编程---UDP
阅读量:4970 次
发布时间:2019-06-12

本文共 5802 字,大约阅读时间需要 19 分钟。

头文件

#include 
#include

函数原型

int sendto (int s, const void *buf, int len, unsigned int flags, const struct sockaddr *to, int tolen);int recvfrom(int s, void *buf, int len, unsigned int flags, struct sockaddr *from, int *fromlen);

编写程序的过程遇到的问题及解决办法都在代码中说明

server

/*************************************************************************    > File Name: server.c    > Author: Chen    > Mail: 971859774@qq.com     > Created Time: 2018年11月12日 星期一 21时30分34秒 ************************************************************************/#include 
#include
#include
#include
#include
#include
#include
#include
#include "my_err.h"#define SERV_PORT 9877void dg_ser(int sockfd,struct sockaddr * cliaddr,socklen_t clilen){ char msg[MAXLINE]; memset(msg,sizeof(msg),0); int index=0; while(1) { socklen_t len=clilen; int n=recvfrom(sockfd,msg,MAXLINE,0,cliaddr,&len); char m[len]; printf("server receive from %s, message: %s",inet_ntop(AF_INET,cliaddr,m,len),msg); sendto(sockfd,msg,n,0,cliaddr,len); } return;}int main(int argc,char **argv){ int sockfd=socket(AF_INET,SOCK_DGRAM,0); struct sockaddr_in servaddr,cliaddr; bzero(&servaddr,sizeof(servaddr)); servaddr.sin_port=htons(SERV_PORT); servaddr.sin_family=AF_INET; servaddr.sin_addr.s_addr=htonl(INADDR_ANY); bind(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr)); char msg[sizeof(servaddr)]; printf("server adress: %s\n",inet_ntop(AF_INET,(struct sockaddr *)&servaddr,msg,sizeof(servaddr))); dg_ser(sockfd,(struct sockaddr *)&cliaddr,sizeof(cliaddr)); return 0;}

 

调用connect的client

/*************************************************************************    > File Name: client.c    > Author: Chen    > Mail: 971859774@qq.com     > Created Time: 2018年11月12日 星期一 20时47分06秒 ************************************************************************/#include 
#include
#include
#include
#include
#include
#include
#include
#include "my_err.h"#define SERV_PORT 9877void dg_cli(int sockfd,const struct sockaddr* servaddr,socklen_t servlen){ char sendline[MAXLINE],recvline[MAXLINE+1]; //调用connect的udp套接字 int res=connect(sockfd,(struct sockaddr *)servaddr,servlen); if(res<0) { fprintf(stderr,"connect error\n"); exit(0); } /*利用connect确定外出接口,因为connect udp套接字的时候,内核自动选 *(假设未显示调用bind),本地ip地址通过为目的ip地址搜索路由表得到的 *外出借口,然后选用该接口的主ip地址而选定 */ struct sockaddr_in cliaddr; socklen_t len=sizeof(cliaddr); getsockname(sockfd,(struct sockaddr *)&cliaddr,&len); char m[len]; printf("local address: %s\n",inet_ntop(AF_INET,(struct sockaddr *)&cliaddr,m,len)); while(fgets(sendline,MAXLINE,stdin)!=NULL) { /* * 如果此时服务器未启动,客户将永远阻塞在recvfrom中。 * 愿意:在客户像服务器发送udp数据报之前,先进行一次arp的请求答应 * 交换,这个 请求交换放在tcpdump中输出中,服务器相应一个端口不可 * 达错误,这也成为异步错误,该错误有sendto引起,但sendto却成功返回 * ,udp输出操作成功返回仅仅表示接口接口队列中具有存放形成的ip数据 * 报的空间,对于udp套接字,由它引发的错误却不返回给他 */ size_t fw=write(sockfd,sendline,strlen(sendline)); if(fw<0) { fprintf(stderr,"write error\n"); exit(0); } size_t n=read(sockfd,recvline,MAXLINE); char *msg=strerror(errno); if(errno==111) { fprintf(stderr,"%s\n",msg); exit(1); } if(n<0) { fprintf(stderr,"read error\n"); } recvline[n]='\0'; fputs(recvline,stdout); bzero(sendline,MAXLINE); bzero(recvline,MAXLINE); } return;}int main(int argv,char **argc){ if(argv!=2) err_quit("please input address"); /* * 客户必须给出服务器的ip和端口号,一般来说客户的端口号和ip由内核自动 * 选则,临时端口号是在第一次sendto时一次性选定的不能改,ip可以变动。 * 也可用bind指定 */ struct sockaddr_in servaddr; bzero(&servaddr,sizeof(servaddr)); servaddr.sin_family=AF_INET; servaddr.sin_port=htons(SERV_PORT); inet_pton(AF_INET,argc[1],&servaddr.sin_addr); int sockfd=socket(AF_INET,SOCK_DGRAM,0); dg_cli(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr)); return 0;}

没有调用connect的client

/*************************************************************************    > File Name: client.c    > Author: Chen    > Mail: 971859774@qq.com     > Created Time: 2018年11月12日 星期一 20时47分06秒 ************************************************************************/#include 
#include
#include
#include
#include
#include
#include
#include
#include "my_err.h"#define SERV_PORT 9877void dg_cli(int sockfd,const struct sockaddr* servaddr,socklen_t servlen){ char sendline[MAXLINE],recvline[MAXLINE]; while(fgets(sendline,MAXLINE,stdin)!=NULL) { /* * 如果此时服务器未启动,客户将永远阻塞在recvfrom中。 * 愿意:在客户像服务器发送udp数据报之前,先进行一次arp的请求答应 * 交换,这个 请求交换放在tcpdump中输出中,服务器相应一个端口不可 * 达错误,这也成为异步错误,该错误有sendto引起,但sendto却成功返回 * ,udp输出操作成功返回仅仅表示接口接口队列中具有存放形成的ip数据 * 报的空间,对于udp套接字,由它引发的错误却不返回给他 */ sendto(sockfd,sendline,strlen(sendline),0,servaddr,servlen); //接受返回来的套接字,判断返回的信息是不是服务器返回的信息 struct sockaddr *rep_ser=malloc(servlen); socklen_t len=servlen; int n=recvfrom(sockfd,recvline,MAXLINE,0,rep_ser,&len); char msg[len]; if(len!=servlen||memcmp(servaddr,rep_ser,len)!=0) { printf("reply from %s (ignore)\n",inet_ntop(AF_INET,rep_ser,msg,len)); continue; } printf("server adress: %s\n",inet_ntop(AF_INET,rep_ser,msg,len)); recvline[n]='\0'; printf("refelect send message:"); fputs(recvline,stdout); } return;}int main(int argv,char **argc){ if(argv!=2) err_quit("please input address"); /* * 客户必须给出服务器的ip和端口号,一般来说客户的端口号和ip由内核自动 * 选则,临时端口号是在第一次sendto时一次性选定的不能改,ip可以变动。 * 也可用bind指定 */ struct sockaddr_in servaddr; bzero(&servaddr,sizeof(servaddr)); servaddr.sin_family=AF_INET; servaddr.sin_port=htons(SERV_PORT); inet_pton(AF_INET,argc[1],&servaddr.sin_addr); int sockfd=socket(AF_INET,SOCK_DGRAM,0); dg_cli(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr)); return 0;}

udp的connect:

tcp udp stcp 详解

转载于:https://www.cnblogs.com/tianzeng/p/9955184.html

你可能感兴趣的文章
POJ-3211 Washing Clothes[01背包问题]
查看>>
Codeforces 518 D Ilya and Escalator
查看>>
[BZOJ4832][Lydsy1704月赛]抵制克苏恩
查看>>
Cheatsheet: 2012 07.11 ~ 07.18
查看>>
Cheatsheet: 2013 08.01 ~ 08.13
查看>>
XCode5无法设置Deployment Target的解决办法
查看>>
关于charles连接手机的配置
查看>>
关于xUtils框架的个人理解
查看>>
SpringMVC案例1——对User表进行CRUD操作
查看>>
用jquery制作一个简单的导航栏
查看>>
MFC中ClistCtrl的=NM_CUSTOMDRAW消息
查看>>
如何去激励自己
查看>>
Crontab定时任务
查看>>
【转载】关于IIS进程池出错终止的故障排查手记
查看>>
SQLServer中服务器角色和数据库角色权限详解
查看>>
《世界是数字的》读后感想
查看>>
可以让javascript加快的脚本(收藏了)
查看>>
【转】Mysql 根据时间戳按年月日分组统计
查看>>
JQuery插件iScroll实现下拉刷新,滚动翻页特效
查看>>
更有效率的使用Visual Studio(二)
查看>>