文档章节

一、TCP C/S:客户端、服务器程序示例

for_
 for_
发布于 2016/06/18 13:25
字数 506
阅读 216
收藏 2

1. 客户端程序

客户端程序从标准输入读取用户输入,发送给服务器,然后读取服务器响应,并将响应打印到标准输出。

以阻塞方式读写套接字。

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

#define MAXBUF      1024
#define SERV_PORT   9000

void str_cli(FILE *fp, int sockfd)
{
    char    sendbuf[MAXBUF], recvbuf[MAXBUF];
    int recvn;

    while (fgets(sendbuf, MAXBUF, fp) != NULL) {
        if (write(sockfd, sendbuf, strlen(sendbuf)) < 0) {
            perror("write");
            return;
        }
        if ((recvn = read(sockfd, recvbuf, sizeof(recvbuf)-1)) < 0) {
            fprintf(stderr, "str_cli: server terminated prematurely");
            return;
        } else if(recvn == 0) {
            fprintf(stderr, "str_cli: read EOF\n");
            return;
        }
        recvbuf[recvn] = '\0';

        fputs(recvbuf, stdout);
    }
}

int main(int argc, char **argv)
{
    int     sockfd;
    struct sockaddr_in servaddr;

    if (argc != 2) {
        fprintf(stderr, "usage: tcpcli <IPaddress>\n");
        return 0;
    }

    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
        perror("socket");
        exit(EXIT_FAILURE);
    }

    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) {
        perror("inet_pton");
        exit(EXIT_FAILURE);
    }

    if (connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0) {
        perror("connect");
        exit(EXIT_FAILURE);
    }

    str_cli(stdin, sockfd);

    exit(EXIT_SUCCESS);
}

2. 服务器程序

服务器接收到客户端连接请求,fork 一个子进程进行处理。

处理过程为,读取客户端数据,然后又将其发送给客户端。

以阻塞方式读写套接字。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <signal.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/wait.h>

#define SERV_PORT   9000
#define LISTENQ     5
#define MAXBUF      1024 

void sig_chld(int signo)
{
    pid_t   pid;
    int     stat;

    while ((pid = waitpid(-1, &stat, WNOHANG)) > 0) {
        fprintf(stderr, "child %d terminated\n", pid);
    }
}

void str_echo(int sockfd)
{
    ssize_t n;
    char    buf[MAXBUF];

    while ((n = read(sockfd, buf, MAXBUF)) > 0) {
        if (write(sockfd, buf, n) < 0) {
            perror("write");
            break;
        }
    }
}

int main(int argc, char **argv)
{
    int         listenfd, connfd;
    pid_t       childpid;
    socklen_t   clilen;
    struct sockaddr_in cliaddr, servaddr;

    if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
        perror("socket");
        exit(EXIT_FAILURE);
    }

    memset(&servaddr, 0x00, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    servaddr.sin_port = htons(SERV_PORT);

    if (bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0) {
        perror("bind");
        exit(EXIT_FAILURE);
    }

    if (listen(listenfd, LISTENQ)) {
        perror("listen");
        exit(EXIT_FAILURE);
    }

    signal(SIGCHLD, sig_chld);

    for ( ; ; ) {
        clilen = sizeof(cliaddr);
        connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &clilen);
        if (connfd < 0) {
            perror("connfd");
            continue;
        }

        if ((childpid = fork()) < 0) {
            perror("fork");
            exit(EXIT_FAILURE);
        } else if (childpid == 0) {
            close(listenfd);
            str_echo(connfd);
            exit(0);
        }
        close(connfd);
    }

    return 0;
}

参考资料

《UNP v1》

© 著作权归作者所有

for_

for_

粉丝 92
博文 47
码字总数 18257
作品 0
深圳
程序员
私信 提问
Java Socket编程(理论)

socket chat: http://www.cn-java.com/download/data/book/socket_chat.pdf 一、网络编程中的两个问题: 1.找到指定主机:IP层负责网络主机的定位; 2.可靠高效的传输数据:TCP层提供面向应用...

YuanyuanL
2015/08/20
33
0
TCP和Http的区别!我都搞懂了,你就别迷糊了!

相信不少初学手机联网开发的朋友都想知道Http与Socket连接究竟有什么区别,希望通过自己的浅显理解能对初学者有所帮助。 1、TCP连接 手机能够使用联网功能是因为手机底层实现了TCP/IP协议,可...

yzbty23
2015/12/22
10.7K
2
网络性能测试工具Iperf/Jperf

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

ljb_job
2018/07/26
0
0
Python网络编程笔记

一、说明 使用套接字进行网络编程,需要先了解一些有关网络编程的背景信息。 1、客户端/服务器架构: 服务器为一个或多个客户端提供所需的服务,存在的目的就是等待客户端的请求,并响应它们,...

PeanutLike
2016/12/01
145
0
HTTP详解(一)

一、socket介绍二、TCP FSM有限状态机三、http相关概念四、http服务器程序 一、socket介绍 1.socket: C/S Client:发起应用请求的程序 Server:响应请求(提供服务)的程序 LISTEN:Socket c/s双方...

MT_IT
2017/11/22
0
0

没有更多内容

加载失败,请刷新页面

加载更多

java通过ServerSocket与Socket实现通信

首先说一下ServerSocket与Socket. 1.ServerSocket ServerSocket是用来监听客户端Socket连接的类,如果没有连接会一直处于等待状态. ServetSocket有三个构造方法: (1) ServerSocket(int port);...

Blueeeeeee
今天
6
0
用 Sphinx 搭建博客时,如何自定义插件?

之前有不少同学看过我的个人博客(http://python-online.cn),也根据我写的教程完成了自己个人站点的搭建。 点此:使用 Python 30分钟 教你快速搭建一个博客 为防有的同学不清楚 Sphinx ,这...

王炳明
昨天
5
0
黑客之道-40本书籍助你快速入门黑客技术免费下载

场景 黑客是一个中文词语,皆源自英文hacker,随着灰鸽子的出现,灰鸽子成为了很多假借黑客名义控制他人电脑的黑客技术,于是出现了“骇客”与"黑客"分家。2012年电影频道节目中心出品的电影...

badaoliumang
昨天
16
0
很遗憾,没有一篇文章能讲清楚线程的生命周期!

(手机横屏看源码更方便) 注:java源码分析部分如无特殊说明均基于 java8 版本。 简介 大家都知道线程是有生命周期,但是彤哥可以认真负责地告诉你网上几乎没有一篇文章讲得是完全正确的。 ...

彤哥读源码
昨天
18
0
jquery--DOM操作基础

本文转载于:专业的前端网站➭jquery--DOM操作基础 元素的访问 元素属性操作 获取:attr(name);$("#my").attr("src"); 设置:attr(name,value);$("#myImg").attr("src","images/1.jpg"); ......

前端老手
昨天
7
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部