一开始,创建完TCP后,没有用listen监听。启动服务器后,再启动TCP客户端,前几次总是打印readline error:success。后面就恢复正常了

服务器端:

#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include <sys/select.h>
#include <sys/time.h>
#include <signal.h>#define SER_PORT 9999
#define BUFLEN 128
#define max(a, b) ((a) < (b) ? (b):(a))void str_echo(int);void signal_chld(int signo)
{pid_t pid;int status;while ((pid = waitpid(-1, &status, WNOHANG)) < 0) {printf("child pid:%d terminated\n", pid);}return;
}ssize_t readline(int fd, void *ptr, int maxsize)
{char *p = ptr;char c;int rc;int n;for (n = 1; n < maxsize; n++) {again:if ((rc = read(fd, &c, 1)) == 1) {*p++ = c;if (c == '\n') break; } else if (rc == 0) {if (n == 1) return 0;else break;}else {if (errno == EINTR) goto again;else return -1;}}*p = 0;return n;
}ssize_t readn(int fd, void *ptr, size_t n)
{char *p = ptr;int nleft = n;int nread;while (nleft > 0) {if ((nread = read(fd, p, nleft)) < 0) {if (errno == EINTR) nread = 0;else return -1;} else if (nread == 0) break;nleft -= nread;p += nread;}return n - nleft;
}ssize_t writen(int fd, void *ptr, size_t n)
{size_t nwriten;size_t nleft = n;char *p = ptr;while (nleft > 0) {if ((nwriten = write(fd, p, nleft)) <= 0) {if (errno == EINTR) nwriten = 0;else return -1;}nleft -= nwriten;p += nwriten;}return n;
}int main(int argc, char **argv)
{struct sockaddr_in servaddr, clientaddr;int listenfd, connfd, udpfd;int on = 1;pid_t child;fd_set rset;int maxfd, nready;int len;int n;char recvline[BUFLEN];memset(&servaddr, 0x00, sizeof(servaddr));servaddr.sin_family = AF_INET;servaddr.sin_port = htons(SER_PORT);servaddr.sin_addr.s_addr = htonl(INADDR_ANY);listenfd = socket(AF_INET, SOCK_STREAM, 0);if (listenfd < 0) {printf("socket error:%s\n", strerror(errno));return -1;}if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) {printf("setsockopt error:%s\n", strerror(errno));close(listenfd);return -1;}if (bind(listenfd, (struct sockaddr*)&servaddr, sizeof(servaddr))) {printf("bind error:%s\n", strerror(errno));close(listenfd);return -1;}if (listen(listenfd, 100) < 0) {printf("listen error:%s\n", strerror(errno));close(listenfd);return -1;}udpfd = socket(AF_INET, SOCK_DGRAM, 0); if (udpfd < 0) {printf("socket error:%s\n", strerror(errno));close(listenfd);  return -1;}memset(&servaddr, 0x00, sizeof(servaddr));servaddr.sin_family = AF_INET;servaddr.sin_port = htons(SER_PORT);   servaddr.sin_addr.s_addr = htonl(INADDR_ANY);  if (bind(udpfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0) {printf("bind updfd error:%s\n", strerror(errno));close(listenfd); close(udpfd);   return -1;} signal(SIGCHLD, signal_chld);maxfd = max(listenfd, udpfd) + 1;FD_ZERO(&rset); for (;;) {FD_SET(listenfd, &rset);  FD_SET(udpfd, &rset);   nready = select(maxfd, &rset, NULL, NULL, NULL);if (nready <= 0) {if (errno == EINTR) continue;else {printf("select error:%s\n", strerror(errno));break;}}     if (FD_ISSET(udpfd, &rset)) {len = sizeof(clientaddr);n = recvfrom(udpfd, recvline, BUFLEN, 0, (struct sockaddr*)&clientaddr, &len);recvline[n] = 0;printf("recvline=%s\n", recvline);sendto(udpfd, recvline, strlen(recvline), 0, (struct sockaddr*)&clientaddr, len);           }if (FD_ISSET(listenfd, &rset)) {connfd = accept(listenfd, (struct sockaddr*)&clientaddr, &len);if ((child = fork()) == 0) {close(listenfd);str_echo(connfd);exit(0);} close(connfd);}} }void str_echo(int fd)
{int n;char recvline[BUFLEN];for (;;) {n = readline(fd, recvline, BUFLEN);//printf("n=%d\n", n);if (n ==  0) return;if (n > 0)writen(fd, recvline, n);}    

TCP客户端代码:

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>#define SIN_PORT 9999
#define BUF_LEN 256
#define max(a, b) ((a) > (b) ? (a) : (b))size_t readline(int fd, void *ptr, int maxsize)
{char *p = ptr;char c;int rc;int n;for (n = 1; n < maxsize; n++) {again:if ((rc = read(fd, &c, 1)) == 1) {*p++ = c;if (c == '\n') break; } else if (rc == 0) {if (n == 1) return 0;else break;}else {if (errno == EINTR) goto again;else return -1;}}*p = 0;return n;
}size_t readn(int fd, void *ptr, size_t n)
{char *p = ptr;int nleft = n;int nread;while (nleft > 0) {if ((nread = read(fd, p, nleft)) < 0) {if (errno == EINTR) nread = 0;else return -1;} else if (nread == 0) break;nleft -= nread;p += nread;}return n - nleft;
}size_t writen(int fd, void *ptr, size_t n)
{size_t nwriten;size_t nleft = n;char *p = ptr;while (nleft > 0) {if ((nwriten = write(fd, p, nleft)) <= 0) {if (errno == EINTR) nwriten = 0;else return -1;}nleft -= nwriten;p += nwriten;}return n;
}void str_cli(FILE *file, int fd)
{char recvline[BUF_LEN], sendline[BUF_LEN];int maxfdp1;fd_set fdset;int ret;int stdineof = 0;FD_ZERO(&fdset);for(;;) {if (stdineof == 0)FD_SET(fileno(file), &fdset);FD_SET(fd, &fdset);maxfdp1 = max(fileno(file), fd) + 1;ret = select(maxfdp1, &fdset, NULL, NULL, NULL);   if (ret <= 0) {continue;}//printf("ret=%d\n", ret);if (FD_ISSET(fd, &fdset)) {if (readline(fd, recvline, BUF_LEN) == 0) {if (stdineof == 1)return;else {printf("readline error:%s\n", strerror(errno));return;}}fputs(recvline, stdout);} if (FD_ISSET(fileno(file), &fdset)) {memset(sendline, 0x00, sizeof(sendline));if (fgets(sendline, BUF_LEN, file) == NULL) {//printf("fgets error:%s\n", strerror(errno));stdineof = 1;shutdown(fd, SHUT_WR);FD_CLR(fileno(file), &fdset);continue;}//printf("len=%d\n", strlen(sendline));writen(fd, sendline, strlen(sendline));}   }
}int main(int argc, char** argv)
{struct sockaddr_in serveraddr;int sockfd;#ifndef ONLINE_JUDGE//freopen("6.4Client.c", "r", stdin);
#endifsockfd = socket(AF_INET, SOCK_STREAM, 0);if (sockfd < 0) {printf("socket error:%s\n", strerror(errno));return -1;}   serveraddr.sin_family = AF_INET;serveraddr.sin_port = htons(SIN_PORT);if (inet_pton(AF_INET, argv[1], &serveraddr.sin_addr) != 1) {printf("inet_pton error:%s\n", strerror(errno));close(sockfd);return -1;}if (connect(sockfd, (struct sockaddr*)&serveraddr, sizeof(serveraddr)) < 0) {printf("connect error:%s\n", strerror(errno));close(sockfd);return -1;}str_cli(stdin, sockfd);exit(0);}

UDP客户端代码:

#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <netinet/in.h>
#include <arpa/inet.h>#define SERV_PORT 9999
#define BUF_LEN 128char *sock_ntop(const struct sockaddr* sockaddr, socklen_t len)
{static char str[BUF_LEN];char portstr[7];struct sockaddr_in *sin;switch (sockaddr->sa_family) {case AF_INET:sin = (struct sockaddr_in*)sockaddr;if (inet_ntop(AF_INET, &sin->sin_addr, str, sizeof(str)) == (const char *)NULL) {printf("inet_ntop error:%s\n", strerror(errno));return NULL;}  if (ntohs(sin->sin_port) != 0) {snprintf(portstr, sizeof(portstr), ":%d", ntohs(sin->sin_port));strcat(str, portstr);}return str;} return NULL;
}void dg_cli(FILE *fp, int sockfd, const struct sockaddr_in * pservaddr, socklen_t servlen)
{int n;char sendline[BUF_LEN], recvline[BUF_LEN];struct sockaddr reply_addr;socklen_t len;if (connect(sockfd, (struct sockaddr*)pservaddr, servlen) < 0) {printf("connect error:%s\n", strerror(errno));return ;}while (fgets(sendline, BUF_LEN, fp) != NULL) {//sendto(sockfd, sendline, strlen(sendline), 0, (struct sockaddr*)pservaddr, servlen); write(sockfd, sendline, strlen(sendline));len = servlen;//n = recvfrom(sockfd, recvline, BUF_LEN, 0, &reply_addr, &len);n = read(sockfd, recvline, BUF_LEN);/*if (len != servlen || memcmp(&reply_addr, pservaddr, len) != 0) {printf("receive (%s) ignored\n", sock_ntop(&reply_addr, len));continue;}*/recvline[n] = 0;fputs(recvline, stdout);}
}int main(int argc, char **argv)
{struct sockaddr_in servaddr;int sock;memset(&servaddr, 0x00, 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("inet_pton error:%s\n", strerror(errno));return -1;}sock = socket(AF_INET, SOCK_DGRAM, 0);   if (sock < 0) {printf("socket error:%s\n", strerror(errno));return -1;}dg_cli(stdin, sock, &servaddr, sizeof(servaddr));return 0;
}

网络编程学习笔记(使用select函数的TCP和UDP回射服务器程序)相关推荐

  1. UNIX网络编程——UDP回射服务器程序(初级版本)以及漏洞分析

    该函数提供的是一个迭代服务器,而不是像TCP服务器那样可以提供一个并发服务器.其中没有对fork的调用,因此单个服务器进程就得处理所有客户.一般来说,大多数TCP服务器是并发的,而大多数UDP服务器是 ...

  2. UNIX网络编程学习笔记(代码超详细解析)(持续更新)

    1. 其他函数准备 1. TCP 回射服务器程序: str_echo 函数 #include "unp.h"void str_echo(int sockfd) {ssize_t n ...

  3. java 网络编程学习笔记

    java 网络编程学习笔记 C/S模式:客户端和服务器 客户端创建流程 1 1.建立Socket端点 2 3 Socket s = new Socket(绑定地址, 绑定端口); 2.确认源数据方式和 ...

  4. [Linux网络编程学习笔记]索引

    一.Linux基本知识 [学习笔记]Linux平台的文件I/O操作 [学习笔记]Linux平台的文件,目录及操作 [Linux学习笔记]标准输入输出 [Linux学习笔记]进程概念及控制 [Linux ...

  5. 编程开发:Linux网络编程学习笔记

    非常全面.通俗易懂.值得借鉴的Linux网络编程学习笔记.关键字:linux linux编程 网络编程 linux网络编程 下载地址:点我下载 特别说明:本资源收集于网络,版权归原作者及版权商所有,仅 ...

  6. 15Java网络编程学习笔记

    Java网络编程学习笔记 文章目录 1 网络基础 1.1 网络通信 1.2 网络 1.3 IP地址 1.5 域名 1.6 端口号 1.7 网络通信协议 1.8 TCP协议 1.9 UDP协议 2 In ...

  7. python网络编程学习笔记(二)

    python网络编程学习(四) 多用途客户端协议 一.ftp 功能:上传下载文件,删除命名文件,建立删除目录,自动压缩,保存目录 1.代码: #coding=utf-8 '''连接远程ftp服务器,显 ...

  8. 网络编程学习笔记(非阻塞accept)

    修改TCP回射客户程序,在跟服务器建立连接后发送一个RST.这种情况可以如下模拟: 一旦建立连接,设置SO_LINGER选项,把l_onoff标志置为1,l_linger时间置为0.在关闭连接时,TC ...

  9. 网络编程学习笔记(getservbyname和getservbyport函数)

    通过服务器的名字而不是服务器端口号来认知它,而且如果从主机到端口号的映射包含在一个文件中(一般是/etc/services),则如果端口号改变,我们所需做的所有改动就是改动文件/etc/service ...

最新文章

  1. mysql 对部分表binlog_MySQL抑制binlog日志中的BINLOG部分的方法
  2. 广度深度都要,亚马逊是如何推动 Alexa 内生成长的?
  3. [Jarvis OJ - PWN]——[XMAN]level3_x64
  4. Java通过Executors提供四种线程池
  5. 哈哈!TCP泄露了操作系统信息···
  6. 数通手稿留档——Multicast
  7. Kali Linux 无线渗透测试入门指南 第一章 配置无线环境
  8. Python中内置函数的介绍
  9. 对方删了你的微信,你列表依然有ta的存在,该不该也把ta删掉?
  10. 四川大学网络教育计算机网考,四川大学网络教育学院课程考试试题-第一学期期末考试卷-计算机文化...
  11. 蒜头君的生日(日期格式)
  12. 基于linux的mplay的mp3程序,基于Linux下的开源wavplay播放器
  13. 【新星计划】Matlab pid参数调节工具箱
  14. conda 安装完了之后安装torch总是失败
  15. 达梦共享集群DM DMDSC集群对比Oracle RAC原理详解
  16. 统一认证中心-auth2.0
  17. 《第五周RFID作业》物联112118 林家辉
  18. 国产手机支持鸿蒙系统,支持国产,支持鸿蒙!国产手机系统终于看到了希望
  19. mysql sql注入工具_SQL注入工具实践
  20. 【转帖】接口测试流程、测试点和测试工具

热门文章

  1. 如何刪除GitHub中的repository
  2. 电影网网站优化-SEO篇
  3. 下列关于python的描述正确的是-下列关于Python的说法,错误的是()。_学小易找答案...
  4. python入门教程完整版(懂中文就能学会)-Python入门教程完整版!(懂中文的就能学会)...
  5. python小程序代码50 到100行-Python代码不到四十行简单暴力,微信跳一跳小程序轻松过万...
  6. python绘制3维图-python——绘制二元高斯分布的三维图像,
  7. python urllib.request 爬虫 数据处理-python爬虫1--urllib请求库之request模块
  8. python爬虫实例-python 爬虫实例
  9. python培训出来的有公司要吗-python培训机构出来好就业吗
  10. python爬虫能干什么-python爬虫能干什么