3socket编程:UDP编程
1 C/S模型—UDP
UDP處理模型
說明:
由于UDP不需要維護連接,程序邏輯簡單了很多,但是UDP協(xié)議是不可靠的,實際上有很多保證通訊可靠性的機制需要在應用層實現(xiàn)。
編譯運行server,在兩個終端里各開一個client與server交互,看看server是否具有并
發(fā)服務的能力。用Ctrl+C關閉server,然后再運行server,看此時client還能否和server聯(lián)
系上。和前面TCP程序的運行結果相比較,體會無連接的含義。
2 案例說明:
Server.c
| #include<stdio.h> #include<stdlib.h> #include<string.h> #include<netinet/in.h> #include<arpa/inet.h> #include<ctype.h> #include"wrap.h" ? #define MAXLINE 80 #define SERV_PORT 8000 ? int main(void) { ??? struct sockaddr_in servaddr,cliaddr; ??? socklen_t cliaddr_len; ??? int sockfd; ??? char buf[MAXLINE]; ??? char str[INET_ADDRSTRLEN]; ??? int i,n; ??? sockfd = Socket(AF_INET,SOCK_DGRAM,0); ? ??? bzero(&servaddr,sizeof(servaddr)); ??? servaddr.sin_family = AF_INET; ??? servaddr.sin_addr.s_addr = htonl(INADDR_ANY); ??? servaddr.sin_port = htons(SERV_PORT); ? ??? Bind(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr)); ? ??? printf("Accepting connections...\n"); ??? while(1) { ??????? cliaddr_len = sizeof(cliaddr); ??????? n = recvfrom(sockfd,buf,MAXLINE,0, ????????????? ?(struct sockaddr *)&cliaddr,&cliaddr_len); ??????? if(n == -1) ??????????? perr_exit("recvfrom error"); ??????? printf("received from %s at PORT %d\n", ??????????? inet_ntop(AF_INET,&cliaddr.sin_addr,str,sizeof(str)), ??????????? ntohs(cliaddr.sin_port)); ??????? for(i = 0;i<n;i++){ ??????????? buf[i] = toupper(buf[i]); ??????? } ??????? n = sendto(sockfd,buf,n,0,(struct sockaddr *)&cliaddr,sizeof(cliaddr)); ??????? if(n== -1) ??????????? perr_exit("sendto error"); ??? } } |
Client.c
| #include<stdio.h> #include<string.h> #include<unistd.h> #include<netinet/in.h> #include<arpa/inet.h> #include"wrap.h" ? #define MAXLINE 80 #define SERV_PORT 8000 ? int main(int argc,char *argv[]) { ??? struct sockaddr_in servaddr; ??? int sockfd,n; ??? char buf[MAXLINE]; ??? char str[INET_ADDRSTRLEN]; ??? socklen_t servaddr_len; ??? ??? sockfd = Socket(AF_INET,SOCK_DGRAM,0); ? ??? bzero(&servaddr,sizeof(servaddr)); ??? servaddr.sin_family = AF_INET; ??? inet_pton(AF_INET,"127.0.0.1",&servaddr.sin_addr); ??? servaddr.sin_port = htons(SERV_PORT); ? ??? while(fgets(buf,MAXLINE,stdin) != NULL) { ??????? n = sendto(sockfd,buf,strlen(buf),0,(struct sockaddr *)&servaddr, ??????????? sizeof(servaddr)); ??????? if(n == -1) ??????????? perr_exit("sendto error"); ??????? n = recvfrom(sockfd,buf,MAXLINE,0,NULL,0); ??????? if(n == -1) ??????????? perr_exit("recvfrom error"); ??????? Write(STDOUT_FILENO,buf,n); ??? } ??? ??? Close(sockfd); ??? return 0; } |
Wrap.h
| #ifndef __WRAP_H_ #define __WRAP_H_ ? void perr_exit(const char *s); int Accept(int fd, struct sockaddr *sa, socklen_t *salenptr); void Bind(int fd, const struct sockaddr *sa, socklen_t salen); void Connect(int fd, const struct sockaddr *sa, socklen_t salen); void Listen(int fd, int backlog); int Socket(int family, int type, int protocol); ssize_t Read(int fd, void *ptr, size_t nbytes); ssize_t Write(int fd, const void *ptr, size_t nbytes); void Close(int fd); ssize_t Readn(int fd, void *vptr, size_t n); ssize_t Writen(int fd, const void *vptr, size_t n); static ssize_t my_read(int fd, char *ptr); ssize_t Readline(int fd, void *vptr, size_t maxlen); ? #endif |
Wrap.c
| #include <stdlib.h> #include <errno.h> #include <sys/socket.h> ? void perr_exit(const char *s) { ???????? perror(s); ???????? exit(1); } ? int Accept(int fd, struct sockaddr *sa, socklen_t *salenptr) { ???????? int n; ? again: ???????? if ( (n = accept(fd, sa, salenptr)) < 0) { ?????????????????? if ((errno == ECONNABORTED) || (errno == EINTR)) ??????????????????????????? goto again; ?????????????????? else ??????????????????????????? perr_exit("accept error"); ???????? } ???????? return n; } ? void Bind(int fd, const struct sockaddr *sa, socklen_t salen) { ???????? if (bind(fd, sa, salen) < 0) ?????????????????? perr_exit("bind error"); } ? void Connect(int fd, const struct sockaddr *sa, socklen_t salen) { ???????? if (connect(fd, sa, salen) < 0) ?????????????????? perr_exit("connect error"); } ? void Listen(int fd, int backlog) { ???????? if (listen(fd, backlog) < 0) ?????????????????? perr_exit("listen error"); } ? int Socket(int family, int type, int protocol) { ???????? int n; ? ???????? if ( (n = socket(family, type, protocol)) < 0) ?????????????????? perr_exit("socket error"); ???????? return n; } ? ssize_t Read(int fd, void *ptr, size_t nbytes) { ???????? ssize_t n; ? again: ???????? if ( (n = read(fd, ptr, nbytes)) == -1) { ?????????????????? if (errno == EINTR) ??????????????????????????? goto again; ?????????????????? else ??????????????????????????? return -1; ???????? } ???????? return n; } ? ssize_t Write(int fd, const void *ptr, size_t nbytes) { ???????? ssize_t n; ? again: ???????? if ( (n = write(fd, ptr, nbytes)) == -1) { ?????????????????? if (errno == EINTR) ??????????????????????????? goto again; ?????????????????? else ??????????????????????????? return -1; ???????? } ???????? return n; } ? void Close(int fd) { ???????? if (close(fd) == -1) ?????????????????? perr_exit("close error"); } ssize_t Readn(int fd, void *vptr, size_t n) { ???????? size_t? nleft; ???????? ssize_t nread; ???????? char?? *ptr; ? ???????? ptr = vptr; ???????? nleft = n; ???????? while (nleft > 0) { ?????????????????? if ( (nread = read(fd, ptr, nleft)) < 0) { ??????????????????????????? if (errno == EINTR) ???????????????????????????????????? nread = 0; ??????????????????????????? else ???????????????????????????????????? return -1; ?????????????????? } else if (nread == 0) ??????????????????????????? break; ? ?????????????????? nleft -= nread; ?????????????????? ptr += nread; ???????? } ???????? return n - nleft; } ? ssize_t Writen(int fd, const void *vptr, size_t n) { ???????? size_t nleft; ???????? ssize_t nwritten; ???????? const char *ptr; ? ???????? ptr = vptr; ???????? nleft = n; ???????? while (nleft > 0) { ?????????????????? if ( (nwritten = write(fd, ptr, nleft)) <= 0) { ??????????????????????????? if (nwritten < 0 && errno == EINTR) ???????????????????????????????????? nwritten = 0; ??????????????????????????? else ???????????????????????????????????? return -1; ?????????????????? } ? ?????????????????? nleft -= nwritten; ?????????????????? ptr += nwritten; ???????? } ???????? return n; } static ssize_t my_read(int fd, char *ptr) { ???????? static int read_cnt; ???????? static char *read_ptr; ???????? static char read_buf[100]; ? ???????? if (read_cnt <= 0) { again: ?????????????????? if ( (read_cnt = read(fd, read_buf, sizeof(read_buf))) < 0) { ??????????????????????????? if (errno == EINTR) ???????????????????????????????????? goto again; ??????????????????????????? return -1; ?????????????????? } else if (read_cnt == 0) ??????????????????????????? return 0; ?????????????????? read_ptr = read_buf; ???????? } ???????? read_cnt--; ???????? *ptr = *read_ptr++; ???????? return 1; } ? ssize_t Readline(int fd, void *vptr, size_t maxlen) { ???????? ssize_t n, rc; ???????? char??? c, *ptr; ? ???????? ptr = vptr; ???????? for (n = 1; n < maxlen; n++) { ?????????????????? if ( (rc = my_read(fd, &c)) == 1) { ??????????????????????????? *ptr++ = c; ??????????????????????????? if (c? == '\n') ???????????????????????????????????? break; ?????????????????? } else if (rc == 0) { ??????????????????????????? *ptr = 0; ??????????????????????????? return n - 1; ?????????????????? } else ??????????????????????????? return -1; ???????? } ???????? *ptr? = 0; ???????? return n; } |
?
總結
以上是生活随笔為你收集整理的3socket编程:UDP编程的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2高并发服务器:多线程服务器
- 下一篇: 阿拉善盟开车到邯郸永年古城多少公里