基于Linux平台实现的流式套接字客户端服务器端代码

(1)服务器段代码如下:

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

#define BUFSIZE 512
/*
 * 错误报告
 */
static void bail(const char *on_what){

    fputs(strerror(errno), stderr);
    fputs(": ", stderr);
    fputs(on_what, stderr);
    fputc('\n', stderr);
    exit(1);
}

int main(int argc, char *argv[]){
   int sockfd;                  /* 服务器套接字 */
    int new_fd;                  /* 服务器连接套接字 */
    struct sockaddr_in server_addr;  /* 服务器监听套接字 */
    struct sockaddr_in client_addr;  /* 客户端IP地址 */

    socklen_t size;
    int portnumber;

    char reqBuf[BUFSIZE];  	/* 应用接收缓存 */
    char dtfmt[BUFSIZE];   	/* 日期-时间结果字符串 */
    time_t td;       		 	/* 当前日期和时间 */
    struct tm tm;    			/* 日期时间结构体 */
    int z;

    if(argc != 2){
        fprintf(stderr, "Usage: %s portnumber\a\n", argv[0]);
        exit(1);
    }

    if((portnumber = atoi(argv[1]))<0){
        fprintf(stderr, "Usage: %s portnumber\a\n", argv[0]);
        exit(1);
    }

    /* 创建服务器监听套接字 */
    if((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1){
        fprintf(stderr, "Socket error: %s\a\n",
                        strerror(errno));
        exit(1);
    }

    /* 为监听套接字准备IP地址和端口 */
    memset(&server_addr, 0, sizeof server_addr);
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    server_addr.sin_port = htons(portnumber);

    /* 绑定套接字到指定地址和端口 */
    if ((bind (sockfd, (struct sockaddr *)(&server_addr),
                        sizeof server_addr)) == -1){
        fprintf(stderr, "Bind error: %s\a\n", strerror(errno));
        exit(1);
    }

    /* 监听 */
    if (listen(sockfd, 128) == -1) {
        fprintf(stderr, "Listen error: %s\n\a",
                        strerror(errno));
        exit(1);
    }
    printf("waiting for the client's request...\n");
    /* 服务器主循环处理 */
    while (1) {
        size = sizeof (struct sockaddr_in);

        /* 接收一个客户端连接并创建服务器连接套接字 */
        if((new_fd = accept(sockfd,
                   (struct sockaddr *)(&client_addr), &size)) == -1){
             fprintf(stderr, "Accept error: %s\a\n",
                            strerror(errno));
             exit(1);
        }

        fprintf(stdout, "Server got connection from %s\n",
            inet_ntoa(client_addr.sin_addr));
        for(;;) {
            /* 读取客户端发来的日期时间请求,若客户端没有发送请求,
             * 则服务器将阻塞
             */
            z = read (new_fd, reqBuf, sizeof reqBuf);
            if(z < 0)
                bail("read()");
            /* 服务器检查客户端是否关闭了套接字,此时read操作
             * 返回0(EOF )。如果客户端关闭了其套接字,则服务器
            * 将执行close 结束此连接,然后开始接收下一个客户端
             * 的连接请求
            */
            if(z == 0) {
               close (new_fd);
                break;
            }
            /*
             * 向请求连接字符串尾添加NULL字符构成完整的请求日
             * 期时间字符串
             */

            reqBuf[z] = 0;

            /*
             * 获得服务器当前日期和时间
             */

            time(&td);
           tm = *localtime(&td);

            /*
             * 根据请求日期字符串的格式字串生成应答字符串
             */
             strftime(dtfmt,  /* 格式化结果 */
            		sizeof dtfmt,
                	reqBuf,        /* 客户端请求格式字串 */
                	&tm);
				/* 将格式化结果发送给客户端 */

             z = write (new_fd, dtfmt, strlen(dtfmt));
             if(z < 0)
				   bail("write()");
          }
       }
   }    

(2)客户端代码:

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

 #define BUFSIZE 512

 static void bail(const char *on_what){
    fputs(strerror(errno), stderr);
     fputs(": ", stderr);
     fputs(on_what, stderr);
     fputc('\n', stderr);
    exit(1);

 }

int main (int argc, char *argv[]) {

    int sockfd;                             /*客户端套接字*/
    char buf[BUFSIZE];
    struct sockaddr_in server_addr;     /* 服务器IP地址*/
    struct hostent *host;
    int portnumber;
    int nbytes;
    int z;
    char reqBuf[BUFSIZE];                 /*客户端请求格式字符串 */
    if (argc != 3) {
        fprintf(stderr, "Usage: %s hostname portnumber\a\n",
                        argv[0]);
        exit(1);

    }
    if ((host = gethostbyname(argv[1])) == NULL) {

        fprintf(stderr, "Gethostname error\n");
       exit(1);

    }
    if ((portnumber = atoi(argv[2])) < 0) {
      fprintf(stderr, "Usage: %s hostname portnumber\a\n",
                       argv[0]);
        exit(1);

    }

    /*创建套接字 */

    if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) {

        fprintf(stderr, "Socket Error: %s\a\n", 

                        strerror(errno));

        exit(1);

    }

    /* 创建服务器地址*/
    memset(&server_addr, 0, sizeof server_addr);
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(portnumber);
    server_addr.sin_addr = *((struct in_addr *)host->h_addr);
    /*链接服务器*/
    if (connect(sockfd, (struct sockaddr *)(&server_addr),
        sizeof server_addr) == -1) {
        fprintf(stderr, "Connect Error: %s\a\n",
                        strerror(errno));
        exit(1);
    }

    printf("connected to server %s\n",
                  inet_ntoa(server_addr.sin_addr));

    /*
    *客户端程序主循环,输入‘quit’退出
    */

   for (;;) {

        /* 提示输入日期时间格式字符串 */
        fputs("\nEnter format string(^D or 'quit' to exit): ",
                      stdout);

        if (!fgets(reqBuf, sizeof reqBuf, stdin)) {
            printf("\n");
            break;      /* EOF */
        }

        /*
        * 为日期时间请求字符串添加NULL字符串作为结尾,另外同时去掉末尾的换行符
        */

       z = strlen(reqBuf);

        if (z > 0 && reqBuf[--z] == '\n')
            reqBuf[z] = 0;
        if (z == 0)  /*客户端进输入了enter */
           continue;
        /*
        * 输入 quit 退出
        */

        if (!strcasecmp(reqBuf, "QUIT")) {
            printf("press any key to end client.\n");
            getchar();
            break;

        }
        /*
        * 发送日期时间请求字符串到服务器,注意请求信息中去掉了NULL字符
        */
       z = write(sockfd, reqBuf, strlen(reqBuf));
        printf("client has sent ??%s?? to the sever\n", reqBuf);
        if (z < 0)
           bail("write()");

        /*
        * 从客户端套接字中读取服务器发回的应答
        */
        if ((nbytes = read(sockfd, buf, sizeof buf)) == -1) {
            fprintf(stderr, "Read Error: %s\n",
                            strerror(errno));
            exit(1);
        }
        /*
        * 若服务器由于某一种原因关闭了链接,则客户段需要处理此事件
        */
      if (nbytes == 0) {  /* ????EOF */

           printf("server has closed the socket.\n");
           printf("press any key to exit...\n");
            getchar();
            break;
        }

        buf[nbytes] = '\0';

       /*
       * 输出日期时间结果
       */
       printf("result from %s port %u :\n\t'%s'\n",
           inet_ntoa(server_addr.sin_addr),
           (unsigned)ntohs(server_addr.sin_port),
            buf);
   }
   close(sockfd);
   return 0;
}

(3)执行程序

时间: 2024-12-28 10:23:40

基于Linux平台实现的流式套接字客户端服务器端代码的相关文章

1.2.1 流式套接字编程

1.2  获取网络中计算机的IP地址和计算机名 在开发网络应用的过程中,经常需要获取网络中某台计算机的IP地址和计算机名称.在本节的内容中,将介绍如何使用Visual C++ 6.0开发一个实现上述功能的应用程序. 1.2.1  流式套接字编程(1) 网络数据的传输是通过套接字实现的.套接字有3种类型:流式套接字(SOCK_ STREAM),数据报套接字(SOCK_DGRAM)及原始套接字(RAW).在本小节的内容中,将首先讲解流式套接字编程的基本知识. 流式套接字是面向连接的,提供双向.有序.

基于流式套接字的回射客服端编程程序

基于流式套接字的回射客服端编程程序 #include <WS2tcpip.h> #include<unistd.h> #include<stdio.h> #include<string.h> #include<stdlib.h> #include <winsock2.h> #define MAXLINE 512 #define PORT 7210 //填服务器端口号 #define IP_ADDRESS "127.0.0.1

流式套接字(SOCK_STREAM),数据报套接字 (SOCK_DGRAM) 的比较

1.流式套接字 使用这种套接字时,数据在客户端是顺序发送的,并且到达的顺序是一致的.比如你在客户端先发送1,再发送2,那么在服务器端的接收顺序是先接收到1,再接收到2,流式套接字是可靠的,是面向连接的: 2.数据报套接字 这种套接字是无连接的,数据是打包成数据包发送的,到达的顺序不一定与发送的顺序是一致的,并且数据不一定是可达的,并且接收到的数据还可能出错. 既然这样那为什么还要使用这种套接字呢?因为现每个使用udp的程序都有自己的对数据进行确认的协议.如TFTP协议规定了每收到一个消息比如,

多客户登录(基于TCP的流式套接字Socket编程)

1.序列化对象 package com.ljb.app.socket; import java.io.Serializable; /**  * 用户类(实现序列化)  * @author LJB  * @version 2015年3月12日  */ public class User implements Serializable{  private String name;  private String password;    public String getName() {   ret

基于Linux平台下网络病毒Caem.c源码及解析

Came.c型病毒在这里主要修改了用户的密码,同时对用户的终端设备进行了监视.希望与大家共同交流 转载请注明出处:http://blog.csdn.net/u010484477     O(∩_∩)O谢谢 #define HOME "/" #define TIOCSCTTY 0x540E #define TIOCGWINSZ 0x5413 #define TIOCSWINSZ 0x5414 #define ECHAR 0x1d #define PORT 39617 #define BU

Linux平台(Centos7)-lnmp一键式部署mysql,nginx,php,php-fpm服务

Linux平台(Centos7)-lnmp一键式部署mysql,nginx,php,php-fpm服务 1. 部署方式1:手动部署. 6 1.1. 配置防火墙. 6 1.2. 关闭firewall 6 1.3. 安装iptables防火墙. 6 1.4. 安装Apache 7 1.5. 安装MariaDB 9 1.5.1. 安装MariaDB 9 1.5.2. 启动服务. 10 1.5.3. 设置开机启动. 10 1.5.4. 为root账户设置密码. 11 1.5.5. 重启MariaDB 1

基于Linux平台下的僵尸网络病毒《比尔盖茨》

感觉分析的很好,所以决定翻译出来,希望和大家多多交流O(∩_∩)O~ 转载请注明出处:http://blog.csdn.net/u010484477     O(∩_∩)O谢谢 关键字:病毒,linux,信息安全 我昨天写的日志里面提到,家用路由器在x86的CentOS系统下奇怪的自己行动,像是在自己加载处理器.于是我决定爬上去看看,在那里发生了什么,然后我马上意识到有人爬到服务器和挂在进程中的dgnfd564sdf.com.主要是下面几个方面atddd,cupsdd,cupsddh, ksap

基于Linux平台病毒BlackHole病毒解析

今天遇到了一个病毒,代码量不多,但是利用了一个函数的小空子,杀伤力确实挺惊人的. 转载请注明出处:http://blog.csdn.net/u010484477谢谢^_^ 这个病毒前面就是常规的: socket->bind->listen这个过程大家都 下面我想详细说一下它的攻击方式: while ( 1 ) { nsock = accept(sock, (struct sockaddr *)&v10, (socklen_t *)&v9);// wait to link if

基于Linux平台病毒Wirenet.c解析

在分析Wirenet.c时,感觉自己学到了很多很赞的思想,希望跟大家一同交流. 转载请注明出处:http://blog.csdn.net/u010484477谢谢^_^ 这次并不想通篇的进行分析了,我想写出两块病毒的恶意代码,觉得思想挺好的. 一.删除某目录下的所有文件 pathpoint = opendir(path);  //打开一个目录 dirent = readdir(pathpoint);//读取目录,返回dirent结构体指针 fdname = dirent->d_name;//得到