文档章节

TCP/UDP 客户端 服务端 简单测试程序

老汉-憨憨
 老汉-憨憨
发布于 2017/07/21 11:39
字数 1284
阅读 25
收藏 0
点赞 0
评论 0

tcpsvr:

#include <stdio.h>  
#include <unistd.h>  
#include <errno.h>  
#include <string.h>  
#include <sys/types.h>  
#include <sys/socket.h>  
#include <stdlib.h>  
#include <arpa/inet.h>  
#include <netinet/in.h>  

#define LY_ERR printf
void accept_handle(int connfd, struct sockaddr_in peeraddr);  

int main(int argc, const char *argv[])  
{  
    int        sockfd, connfd;  
    struct sockaddr_in  seraddr, peeraddr;  
    socklen_t  addrlen;  

    if (argc != 2) {  
        printf("Usage: %s <port>\n", argv[0]);  
        return -1;  
    }  

    sockfd = socket(AF_INET, SOCK_STREAM, 0);  
    if (sockfd < 0) {  
        LY_ERR("socket: %s\n", strerror(errno));  
        return -1;  
    }  
   
    setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, (int[]){1}, sizeof(int));


    seraddr.sin_family = AF_INET;  
    seraddr.sin_port = ntohs(atoi(argv[1]));  
    seraddr.sin_addr.s_addr = htonl(INADDR_ANY);  

    if (bind(sockfd, (struct sockaddr *)&seraddr, sizeof(struct sockaddr))) {  
        LY_ERR("bind: %s\n", strerror(errno));  
        return -1;  
    }  
   
    #define MAX_CONN (10)
    if (listen(sockfd, MAX_CONN) < 0) {  
        LY_ERR("listen: %s\n", strerror(errno));  
        return -1;  
    }  

    addrlen = sizeof(struct sockaddr);  
    for (;;) {  
        connfd = accept(sockfd, (struct sockaddr *)(&peeraddr), &addrlen);  
        if (connfd < 0) {  
            LY_ERR("accept: %s\n", strerror(errno));  
            continue;  
        }  
        accept_handle(connfd, peeraddr);  
    }  

    return 0;  
}  

void accept_handle(int connfd, struct sockaddr_in peeraddr)  
{  
    char   buf1[32] = "Hello, welcome to server!";  
    char   buf[32]; 
    printf("Receive request from %s, port %d\n",  
            inet_ntop(AF_INET, &peeraddr.sin_addr, buf, sizeof(buf)),  
            ntohs(peeraddr.sin_port));  

    if (send(connfd, buf1, sizeof(buf1), 0) < 0) {  
        close(connfd);  
        return;  
    }  

    close(connfd);  
}  

tcpcli:

/* 
 * tcpclient.c - A simple TCP client
 * usage: tcpclient <host> <port>
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h> 
#include <errno.h>
#include <poll.h>

#define BUFSIZE 1024

/* 
 * error - wrapper for perror
 */
void error(char *msg) {
    perror(msg);
    exit(0);
}

int main(int argc, char **argv) 
{
    int sockfd, portno, n;
    struct sockaddr_in serveraddr, cli;
    struct hostent *server;
    char *hostname;
    char buf[BUFSIZE];

    /* check command line arguments */
    if (argc != 3) {
        fprintf(stderr,"usage: %s <hostname> <port>\n", argv[0]);
        exit(0);
    }

    hostname = argv[1];
    portno = atoi(argv[2]);

    /* socket: create the socket */
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0) 
        error("ERROR opening socket");

    int enable = 1;
    if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int)) < 0)
        error("setsockopt(SO_REUSEADDR) failed");

#if 1 
    /* 客户端也是可以绑定某个端口的 */
    bzero((char *)&cli, sizeof(cli));
    cli.sin_family = AF_INET;  
    cli.sin_port = ntohs(3307);  
    cli.sin_addr.s_addr = htonl(INADDR_ANY);  

    if (bind(sockfd, (struct sockaddr *)&cli, sizeof(struct sockaddr))) {   
        printf("bind: %s\n", strerror(errno));  
        return -1;  
    } 
#endif

    server = gethostbyname(hostname);
    if (server == NULL) {
        fprintf(stderr,"ERROR, no such host as %s\n", hostname);
        exit(0);
    }

    /* build the server's Internet address */
    bzero((char *) &serveraddr, sizeof(serveraddr));
    serveraddr.sin_family = AF_INET;
    bcopy((char *)server->h_addr, 
            (char *)&serveraddr.sin_addr.s_addr, server->h_length);
    serveraddr.sin_port = htons(portno);


    /* connect: create a connection with the server */
    if (connect(sockfd, (const sockaddr*)&serveraddr, sizeof(serveraddr)) < 0)  {
        printf("errno = %d\n", errno);
        error("ERROR connecting");
    }
    printf("conn success!");

    /* print the server's reply */
    bzero(buf, BUFSIZE);
    n = read(sockfd, buf, 4);
    if (n < 0) { 
        error("ERROR reading from socket");
    }

    n = read(sockfd, buf+4, BUFSIZE-4);
    if (n < 0) { 
        error("ERROR reading from socket");
    }
    printf("Echo from server: %s, %d\n", buf, n);

    close(sockfd);
    return 0;
}

TCP Client 这里调用了两次 read 是为了和 udp 的做一个对比。TCP 这里,server发一次, client read 两次会正常返回, 程序正常结束(前提是 svr 发送的数据长度 >4).

udpsvr:

/* 
 *  * udpserver.c - A simple UDP echo server 
 *   * usage: udpserver <port>
 *    */

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h> 
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#define BUFSIZE 1024

/*
 *  * error - wrapper for perror
 *   */
void error(char *msg) {
    perror(msg);
    exit(1);
}

int main(int argc, char **argv) {
    int sockfd; /* socket */
    int portno; /* port to listen on */
    int clientlen; /* byte size of client's address */
    struct sockaddr_in serveraddr; /* server's addr */
    struct sockaddr_in clientaddr; /* client addr */
    struct hostent *hostp; /* client host info */
    char buf[BUFSIZE]; /* message buf */
    char *hostaddrp; /* dotted decimal host addr string */
    int optval; /* flag value for setsockopt */
    int n; /* message byte size */

    /* 
     *    * check command line arguments 
     *       */
    if (argc != 2) {
        fprintf(stderr, "usage: %s <port>\n", argv[0]);
        exit(1);
    }
    portno = atoi(argv[1]);

    /* 
     *    * socket: create the parent socket 
     *       */
    sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (sockfd < 0) 
        error("ERROR opening socket");

    /* setsockopt: Handy debugging trick that lets 
     *    * us rerun the server immediately after we kill it; 
     *       * otherwise we have to wait about 20 secs. 
     *          * Eliminates "ERROR on binding: Address already in use" error. 
     *             */
    optval = 1;
    setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, 
            (const void *)&optval , sizeof(int));

    /*
     *    * build the server's Internet address
     *       */
    bzero((char *) &serveraddr, sizeof(serveraddr));
    serveraddr.sin_family = AF_INET;
    serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
    serveraddr.sin_port = htons((unsigned short)portno);

    /* 
     *    * bind: associate the parent socket with a port 
     *       */
    if (bind(sockfd, (struct sockaddr *) &serveraddr, 
                sizeof(serveraddr)) < 0) 
        error("ERROR on binding");

    /* 
     *    * main loop: wait for a datagram, then echo it
     *       */
    clientlen = sizeof(clientaddr);
    while (1) {

        /*
         *      * recvfrom: receive a UDP datagram from a client
         *           */
        bzero(buf, BUFSIZE);
        n = recvfrom(sockfd, buf, 3, 0,
                (struct sockaddr *) &clientaddr, &clientlen);
        if (n < 0)
            error("ERROR in recvfrom");

        n = recvfrom(sockfd, buf + 3, (BUFSIZE - 3), 0,
                (struct sockaddr *) &clientaddr, &clientlen);
        if (n < 0)
            error("ERROR in recvfrom");

        /* 
         *      * gethostbyaddr: determine who sent the datagram
         *           */
        hostp = gethostbyaddr((const char *)&clientaddr.sin_addr.s_addr, 
                sizeof(clientaddr.sin_addr.s_addr), AF_INET);
        if (hostp == NULL)
            error("ERROR on gethostbyaddr");
        hostaddrp = inet_ntoa(clientaddr.sin_addr);
        if (hostaddrp == NULL)
            error("ERROR on inet_ntoa\n");
        printf("server received datagram from %s (%s)\n", 
                hostp->h_name, hostaddrp);
        printf("server received %d/%d bytes: %s\n", strlen(buf), n, buf);

        /* 
         *      * sendto: echo the input back to the client 
         *           */
        n = sendto(sockfd, buf, strlen(buf), 0, 
                (struct sockaddr *) &clientaddr, clientlen);
        if (n < 0) 
            error("ERROR in sendto");
    }
}

Udp Svr 里面调用了两次 readfrom!!!

 

udpcli:

/* 
 *  * udpclient.c - A simple UDP client
 *   * usage: udpclient <host> <port>
 *    */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h> 

#define BUFSIZE 1024

/* 
 *  * error - wrapper for perror
 *   */
void error(char *msg) {
    perror(msg);
    exit(0);
}

int main(int argc, char **argv) {
    int sockfd, portno, n;
    int serverlen;
    struct sockaddr_in serveraddr;
    struct hostent *server;
    char *hostname;
    char buf[BUFSIZE];

    /* check command line arguments */
    if (argc != 3) {
        fprintf(stderr,"usage: %s <hostname> <port>\n", argv[0]);
        exit(0);
    }
    hostname = argv[1];
    portno = atoi(argv[2]);

    /* socket: create the socket */
    sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (sockfd < 0) 
        error("ERROR opening socket");

    /* gethostbyname: get the server's DNS entry */
    server = gethostbyname(hostname);
    if (server == NULL) {
        fprintf(stderr,"ERROR, no such host as %s\n", hostname);
        exit(0);
    }

    /* build the server's Internet address */
    bzero((char *) &serveraddr, sizeof(serveraddr));
    serveraddr.sin_family = AF_INET;
    bcopy((char *)server->h_addr, 
            (char *)&serveraddr.sin_addr.s_addr, server->h_length);
    serveraddr.sin_port = htons(portno);

    /* get a message from the user */
    bzero(buf, BUFSIZE);
    printf("Please enter msg: ");
    fgets(buf, BUFSIZE, stdin);

    /* send the message to the server */
    serverlen = sizeof(serveraddr);
    n = sendto(sockfd, buf, strlen(buf), 0, (const struct sockaddr *)(&serveraddr), serverlen);
    if (n < 0) 
        error("ERROR in sendto");

    serverlen = sizeof(serveraddr);
    n = sendto(sockfd, buf, strlen(buf), 0, (const struct sockaddr *)(&serveraddr), serverlen);
    if (n < 0) 
        error("ERROR in sendto");

    /* print the server's reply */
    n = recvfrom(sockfd, buf, strlen(buf), 0, (struct sockaddr *)(&serveraddr), &serverlen);
    if (n < 0) 
        error("ERROR in recvfrom");
    printf("Echo from server: %s", buf);
    return 0;
}

udp 这里调用了两次 sendto, 如果只调用一次 sendto, 那么 udp srv 就会阻塞在第二个 readfrom 即便你发送的数据长度大于 3 字节.

udp 的输入与输出:

./server 10003
server received datagram from localhost (127.0.0.1)
server received 14/11 bytes: 1231234567890

./client 127.0.0.1 10003
Please enter msg: 1234567890
Echo from server: 12312345678

具体原理可以参考:

https://my.oschina.net/tsh/blog/995626

© 著作权归作者所有

共有 人打赏支持
老汉-憨憨
粉丝 18
博文 322
码字总数 68382
作品 0
深圳
程序员
网络性能测试工具Iperf介绍

【概要】Iperf是一款网络性能测试工具,可以方便的用它进行SDN网络带宽和网络质量的测试,Iperf支持协议、定时、缓冲区等参数的配置调整,报告TCP/UDP最大带宽、延迟抖动、数据包丢失等统计信...

SDN_LAB
2014/12/04
0
1
android中的socket

什么是Socket? 所谓Socket通常也称作“套接字”,用于描述IP地址和端口,是一个通信连的句柄,应用程序通常通过“套接字”向网络发送请求或者应答网络请求,它就是网络通信过程中端点的抽象表...

一别经年
2013/12/28
0
0
Udp、Tcp、Http Socket

1.TCP与UDP 面向报文的传输方式是应用层交给UDP多长的报文,UDP就照样发送,即一次发送一个报文。因此,应用程序必须选择合适大小的报文。若报文太长,则IP层需要分片,降低效率。若太短,会...

V_joy
2016/07/26
45
0
高性能 Socket 组件 HP-Socket v2.3.1-beta-2 发布

HP-Socket 是一套通用的高性能 Windows Socket 组件包,包含服务端组件(IOCP 模型)和客户端组件(Event Select 模型),广泛适用于 Windows 平台的 TCP/UDP 通信系统。HP-Socket 对通信层实...

伤神小怪兽
2013/10/24
2.2K
6
网络测试工具--Iperf、MZ使用技巧

Iperf Iperf 是一个网络性能测试工具。Iperf可以测试最大TCP和UDP带宽性能,具有多种参数和UDP特性,可以根据需要调整,可以报告带宽、延迟抖动和数据包丢失。 0 客户端与服务器共用选项 服务...

造梦先森Kai的专栏
2017/12/18
0
0
循序渐进Java Socket网络编程(多客户端、信息共享、文件传输)

前言:在最近一个即将结束的项目中使用到了Socket编程,用于调用另一系统进行处理并返回数据。故把Socket的基础知识总结梳理一遍。 一、TCP/IP协议   既然是网络编程,涉及几个系统之间的交...

大数据之路
2013/01/25
0
9
114-给 udp 增加可靠性(二)

这一节的目标是完成一个最简单的尽量可靠 UDP 程序,实现的功能如下: 客户端给服务端发送数据,服务端收到数据后立即将数据原样发送回去,进行确认。 客户端收到服务端的确认后,检查是不是...

q1007729991
01/28
0
0
【新年呈献】高性能 Socket 组件 HP-Socket v3.1.2 正式发布

  HP-Socket 是一套通用的高性能 Windows Socket 组件包,包含服务端组件(IOCP 模型)和客户端组件(Event Select 模型),广泛适用于 Windows 平台的 TCP/UDP 通信系统。HP-Socket 对通信...

伤神小怪兽
2014/01/13
2.4K
16
Iperf网络检测工具

一、介绍 Iperf是一个网络性能测试工具。Iperf可以测试TCP和UDP带宽质量。Iperf可以测量最大TCP带宽,具有多种参数和UDP特性。 Iperf可以报告带宽,延迟抖动和数据包丢失。利用Iperf这一特性...

80后小菜鸟
2017/07/12
0
0
安全运维之:网络性能评估工具Iperf

一、 网络性能评估工具Iperf 网络性能评估主要是监测网络带宽的使用率,将网络带宽利用最大化是保证网络性能的基础,但是由于网络设计不合理、网络存在安全漏洞等原因,都会导致网络带宽利用...

ning235
2014/10/23
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

python上传文件

f=request.FILES.get('fafa') ff=open(f.name,mode='wb') for i in f.chunks(): ff.write(i) ff.close()...

南桥北木
4分钟前
0
0
CISCO VPN Client Reason 442 WIN8/10错误解决方案

http://jdkleo.iteye.com/blog/2163493 引用 http://my.oschina.net/cloudcoder/blog/220391?p={{currentPage 1}} 在使用cisco VPN 客户端登录时,产生Reason 442:Failedto enable Virtual......

chenfj_fer
7分钟前
0
0
信号量有没有容量限制?

之前一直误以为信号量初始化的时候那个初始化的值是信号量的“容量”,昨天同事指出了我的错误,最初我是不相信的,经过以下代码实践,证明了我的错误: Java版: import java.util.concurr...

锟斤拷烫烫烫
11分钟前
0
0
【RocketMQ】Message存储笔记

概述 消息中间件存储分为三种,一是保存在内存中,速度快但会因为系统宕机等因素造成消息丢失;二是保存在内存中,同时定时将消息写入DB中,好处是持久化消息,如何读写DB是MQ的瓶颈;三是内...

SaintTinyBoy
22分钟前
0
0
Android应用Context详解及源码解析

Android应用Context详解及源码解析 本文定位:优质文章收集 本文转载 1 背景 今天突然想起之前在上家公司(做TV与BOX盒子)时有好几个人问过我关于Android的Context到底是啥的问题,所以就马...

lichuangnk
53分钟前
0
0
PostgreSQL的昨天今天和明天

PostgreSQL 是一种非常复杂的对象-关系型数据库管理系统(ORDBMS), 也是目前功能最强大,特性最丰富和最复杂的自由软件数据库系统。有些特性甚至连商业数据库都不具备。 这个起源于伯克利(...

闻术苑
58分钟前
1
0
Mysql对自增主键ID进行重新排序

1,删除原有主键: ALTER TABLE `table_name` DROP `id`; 2,添加新主键字段: ALTER TABLE `table_name` ADD `id` MEDIUMINT( 8 ) NOT NULL FIRST; 3,设置新主键: ALTER TABLE `table_nam......

niithub
今天
0
0
福利篇:免费csdn vip账号分享

分享一个发布免费csdn vip账号的网站:啰嗦vip www.lostvip.com , 各种软件开发类的视频教程:慕课网、动脑学院、黑马各大培训机构VIP视频教程,非常不错!

在水一方发盐人
今天
0
0
Nginx+Tomcat搭建高性能负载均衡集群

一、 工具   nginx-1.8.0   apache-tomcat-6.0.33 二、 目标   实现高性能负载均衡的Tomcat集群:    三、 步骤   1、首先下载Nginx,要下载稳定版:      2、然后解压两个Tom...

码代码的小司机
今天
0
0
Centos7编译安装ntp-4.2.8p11

Centos7编译安装ntp-4.2.8p11 背景 因公司做等保评级,在进行安全漏洞检测时发现ntp需要升级到ntp-4.2.7p25以上版本,经过一番搜索,没有该版本及新版本ntp的yum安装包,所以只能编译安装了,...

阿dai
今天
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部