UNP函数笔记六: 基本UDP套接字编程
来源:互联网 发布:平屋面保温层算法 编辑:程序博客网 时间:2024/04/26 15:34
第八章 基本UDP套接字编程:
#include <sys/socket.h>ssize_t recvfrom(int sockfd, void * buff, size_t nbytes, int flags, struct sockaddr * from, socklen_t * addrlen); success return read-bytes(0 means recv a empty package), error return -1 so it is different from tcp-read/recv(0 means get FIN) since it can use by tcp socketssize_t sendto(int sockfd, const void * buff, size_t nbytes, in flags, const struct sockaddr * to, socklen_t addrlen); success return write-bytes, error return -1 we can send a empty package(0 bytes) it can use by tcp socket
示例:
#ifndef __ERROR_EXIT_H__#define __ERROR_EXIT_H__#include <stdio.h>#include <errno.h>#include <string.h>#include <stdlib.h>void err_exit(const char * msg){ printf("%s: %s\n", msg, strerror(errno)); exit(1);}#endif
#include <netinet/in.h>#include <sys/socket.h>#include "dg_echo.h"#include "err_exit.h"#define SERV_PORT 34567int main(int argc, char * argv[]){ int sockfd; struct sockaddr_in servaddr; struct sockaddr_in cliaddr; if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { err_exit("socket error"); } bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_port = htons(SERV_PORT); if (bind(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) == -1) { err_exit("bind error"); } dg_echo(sockfd, (struct sockaddr *)&cliaddr, sizeof(cliaddr));}
#include <netinet/in.h>#include <sys/socket.h>#include "err_exit.h"#define MAXLINE 4096void dg_echo(int sockfd, struct sockaddr * pcliaddr, socklen_t clilen){ int n; socklen_t len; char mesg[MAXLINE]; for ( ; ; ) { len = clilen; if ((n = recvfrom(sockfd, mesg, MAXLINE, 0, pcliaddr, &len)) == -1) { err_exit("recvfrom error"); } if (sendto(sockfd, mesg, n, 0, pcliaddr, len) == -1) { err_exit("sendto error"); } }}
#include <netinet/in.h>#include <sys/socket.h>#include "dg_cli.h"#include "err_exit.h"#define SERV_PORT 34567int main(int argc, char * argv[]){ int sockfd; struct sockaddr_in servaddr; if (argc != 2) { printf("usage: udpcli <IPaddress>\n"); exit(1); } 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) { err_exit("inet_pton error"); } if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { err_exit("socket error"); } dg_cli(stdin, sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)); exit(0);}
#include <netinet/in.h>#include <sys/socket.h>#include "err_exit.h"#define MAXLINE 4096void dg_cli(FILE * fp, int sockfd, const struct sockaddr * pservaddr, socklen_t servlen){ int n; char sendline[MAXLINE]; char recvline[MAXLINE + 1]; while (fgets(sendline, MAXLINE, fp) != NULL) { if (sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen) == -1) { err_exit("sendto error"); } if ((n = recvfrom(sockfd, recvline, MAXLINE, 0, NULL, NULL)) == -1) { err_exit("recvfrom error"); } recvline[n] = 0; /* null terminate */ if (fputs(recvline, stdout) == EOF) { err_exit("fputs error"); } }}
#include <netinet/in.h>#include <sys/socket.h>#include "err_exit.h"#include "sock_ntop.h"#define MAXLINE 4096void dg_cli(FILE * fp, int sockfd, const struct sockaddr * pservaddr, socklen_t servlen){ int n; char sendline[MAXLINE]; char recvline[MAXLINE + 1]; char * paddr; socklen_t len; struct sockaddr * preply_addr; if ((preply_addr = malloc(servlen)) == NULL) { err_exit("malloc error"); } while (fgets(sendline, MAXLINE, fp) != NULL) { if (sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen) == -1) { err_exit("sendto error"); } len = servlen; if ((n = recvfrom(sockfd, recvline, MAXLINE, 0, preply_addr, &len)) == -1) { err_exit("recvfrom error"); } /* * it is not a good idea to use "memcmp" * cause may sendto-remote-ip and recvfrom-remote-ip is different * but they are in a same machine * so we may drop a right response */ if (len != servlen || memcmp(pservaddr, preply_addr, len) != 0) { if ((paddr = sock_ntop(preply_addr, len)) == NULL) { err_exit("sock_ntop error"); } printf("reply from %s (ignored)\n", paddr); continue; } recvline[n] = 0; /* null terminate */ if (fputs(recvline, stdout) == EOF) { err_exit("fputs error"); } }}
#include <netinet/in.h>#include <sys/socket.h>#include "err_exit.h"#define MAXLINE 4096void dg_cli(FILE * fp, int sockfd, const struct sockaddr * pservaddr, socklen_t servlen){ int n; char sendline[MAXLINE]; char recvline[MAXLINE + 1]; if (connect(sockfd, (struct sockaddr *)pservaddr, servlen) == -1) { err_exit("connect error"); } while (fgets(sendline, MAXLINE, fp) != NULL) { if (write(sockfd, sendline, strlen(sendline)) == -1) { err_exit("write error"); } if ((n = read(sockfd, recvline, MAXLINE)) == -1) { err_exit("read error"); } recvline[n] = 0; /* null terminate */ if (fputs(recvline, stdout) == EOF) { err_exit("fputs error"); } }}
#include <netinet/in.h>#include <sys/socket.h>#include "err_exit.h"#define NDG 2000 /* datagrams to send */#define DGLEN 1400 /* length of each datagram */voiddg_cli(FILE * fp, int sockfd, const struct sockaddr * pservaddr, socklen_t servlen){ int i; char sendline[DGLEN]; for (i = 0; i < NDG; i++) { if (sendto(sockfd, sendline, DGLEN, 0, pservaddr, servlen) == -1) { err_exit("sendto error"); } }}
#include <netinet/in.h>#include <sys/socket.h>#include "err_exit.h"#include "my_signal.h"#define MAXLINE 4096int count;void recvfrom_int(int signo){ printf("\nreceived %d datagrams\n", count); exit(0);}void dg_echo(int sockfd, struct sockaddr * pcliaddr, socklen_t clilen){ socklen_t len; char mesg[MAXLINE]; if (my_signal(SIGINT, recvfrom_int) == SIG_ERR) { err_exit("my_signal error"); } for ( ; ; ) { len = clilen; if (recvfrom(sockfd, mesg, MAXLINE, 0, pcliaddr, &len) == -1) { err_exit("recvfrom error"); } count++; }}
#include <netinet/in.h>#include <sys/socket.h>#include "err_exit.h"#include "my_signal.h"#define MAXLINE 4096int count;void recvfrom_int(int signo){ printf("\nreceived %d datagrams\n", count); exit(0);}void dg_echo(int sockfd, struct sockaddr * pcliaddr, socklen_t clilen){ int n; socklen_t len; char mesg[MAXLINE]; if (my_signal(SIGINT, recvfrom_int) == SIG_ERR) { err_exit("my_signal error"); } n = 220 * 1024; if (setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &n, sizeof(n)) == -1) { err_exit("setsockopt error"); } for ( ; ; ) { len = clilen; if (recvfrom(sockfd, mesg, MAXLINE, 0, pcliaddr, &len) == -1) { err_exit("recvfrom error"); } count++; }}
#include <netinet/in.h>#include <sys/socket.h>#include "err_exit.h"#include "sock_ntop.h"#define SERV_PORT 34567int main(int argc, char * argv[]){ int sockfd; char * paddr; socklen_t len; struct sockaddr_in cliaddr; struct sockaddr_in servaddr; if (argc != 2) { printf("usage: udpcli <IPaddress>\n"); exit(0); } if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { err_exit("socket error"); } 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) { err_exit("inet_pton error"); } if (connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) == -1) { err_exit("connect error"); } len = sizeof(cliaddr); if (getsockname(sockfd, (struct sockaddr *)&cliaddr, &len) == -1) { err_exit("getsockname error"); } if ((paddr = sock_ntop((struct sockaddr *)&cliaddr, len)) == NULL) { err_exit("sock_ntop error"); } printf("local address %s\n", paddr); exit(0);}
#include <netinet/in.h>#include <sys/socket.h>#include <sys/select.h>#include <sys/wait.h>#include "str_echo.h"#include "err_exit.h"#include "my_signal.h"#define LISTENQ 1024#define SERV_PORT 34567#define max(a, b) ((a) >= (b) ? (a) : (b))void sig_chld(int signo){ pid_t pid; int stat; while ((pid = waitpid(-1, &stat, WNOHANG)) > 0) { /* waitpid + WNOHANG */ printf("child %d terminated\n", pid); } return;}int main(int argc, char * argv[]){ int listenfd; int connfd; int udpfd; int nready; int maxfdp1; char mesg[MAXLINE]; pid_t childpid; fd_set rset; ssize_t n; socklen_t len; const int on = 1; struct sockaddr_in cliaddr; struct sockaddr_in servaddr; /* create listening TCP socket */ if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { err_exit("socket SOCK_STREAM error"); } bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_port = htons(SERV_PORT); if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1) { err_exit("setsockopt error"); } if (bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) == -1) { err_exit("bind error"); } if (listen(listenfd, LISTENQ) == -1) { err_exit("listen error"); } /* create UDP socket */ if ((udpfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { err_exit("socket SOCK_DGRAM error"); } bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_port = htons(SERV_PORT); if (bind(udpfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) == -1) { err_exit("bind error"); } if (my_signal(SIGCHLD, sig_chld) == SIG_ERR) { /* must call waitpid() */ err_exit("my_signal error"); } FD_ZERO(&rset); maxfdp1 = max(listenfd, udpfd) + 1; for ( ; ; ) { FD_SET(listenfd, &rset); FD_SET(udpfd, &rset); if ((nready = select(maxfdp1, &rset, NULL, NULL, NULL)) == -1) { if (errno == EINTR) { continue; /* back to for() */ } else { err_exit("select error"); } } if (FD_ISSET(listenfd, &rset)) { len = sizeof(cliaddr); connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &len); if (connfd == -1) { err_exit("accept error"); } if ((childpid = fork()) < 0) { err_exit("fork error"); } else if (childpid == 0) { if (close(listenfd) == -1) { err_exit("close listenfd error"); } str_echo(connfd); /* process the request */ exit(0); } if (close(connfd) == -1) { err_exit("close connfd error"); } } if (FD_ISSET(udpfd, &rset)) { len = sizeof(cliaddr); if ((n = recvfrom(udpfd, mesg, MAXLINE, 0, (struct sockaddr *)&cliaddr, &len)) == -1) { err_exit("recvfrom error"); } if (sendto(udpfd, mesg, n, 0, (struct sockaddr *)&cliaddr, len) == -1) { err_exit("sendto error"); } } }}
- UNP函数笔记六: 基本UDP套接字编程
- UNP卷一学习笔记:基本UDP套接字编程
- UNP函数笔记二: 基本TCP套接字编程
- UNP函数笔记七: 基本SCTP套接字编程
- UNP总结 Chapter 8 基本UDP套接字编程
- UNP学习笔记(第八章 基本UDP套接字编程)
- UNP笔记(2)——基本套接字编程
- UNP函数笔记一: 套接字编程简介
- UNP学习:基本套接字编程
- apue和unp的学习之旅10——基本udp套接字编程
- UNP函数笔记五: 套接字选项
- unp读书笔记——udp套接字编程
- 基本UDP套接字编程
- 基本UDP套接字编程
- 基本UDP套接字编程
- 基本UDP套接字编程
- UNP学习笔记(第四章 基本TCP套接字编程)
- UNP总结 Chapter 4 基本TCP套接字编程
- HDU 1823 二维线段树
- poj 2084 Game of Connections
- UltraEdit UEStudio 恢复默认窗口设置
- 从 C++ 到 Objective-C
- 对Flush原理的个人理解
- UNP函数笔记六: 基本UDP套接字编程
- SSH开发中遇到的问题及解决方法
- crontab 启动 、运行 和编辑 查看
- [环境配置]JDK+eclipse(m2e,svn)+svn+maven
- java.util.LinkedList
- linux c shell proc
- 八皇后的一个回溯递归解法
- OpenGl学习之glRotate函数
- 算法学习【10】—— 1006. Team Rankings