Chinaunix首页 | 论坛 | 博客
  • 博客访问: 822809
  • 博文数量: 92
  • 博客积分: 1498
  • 博客等级: 上尉
  • 技术积分: 993
  • 用 户 组: 普通用户
  • 注册时间: 2009-09-18 18:31
文章分类

全部博文(92)

文章存档

2013年(2)

2012年(3)

2011年(3)

2010年(61)

2009年(23)

分类: LINUX

2010-07-25 21:28:42

学习了socket之后,简单的写了个基于C/S的小程序,程序很简单,client给server发送一句话,server计算
出这句话有多少个字节,发送给client。client将字节数打印到标准输出,server将发送出来的话也打印到终
端。不多废话,看代码:

server.c

#include

#include

#include

#include

#include

#include

#include

#include


extern void sig_proccess(int signo);


#define PORT 8888 /* 侦听端口地址 */

#define BACKLOG 2 /* 侦听队列长度 */

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

{

int ss,sc; /* ss为服务器的socket描述符,sc为客户端的socket描述符 */

struct sockaddr_in server_addr; /* 服务器地址结构 */

struct sockaddr_in client_addr; /* 客户端地址结构 */

int err; /* 返回值 */

pid_t pid; /* 分叉的进行id */

signal(SIGINT, sig_proccess);

signal(SIGPIPE, sig_proccess);

/* 建立一个流式套接字 */

ss = socket(AF_INET, SOCK_STREAM, 0);

if(ss < 0){/* 出错 */

printf("socket error\n");

return -1;

}

/* 设置服务器地址 */

bzero(&server_addr, sizeof(server_addr)); /* 清0 */

server_addr.sin_family = AF_INET; /* 协议族 */

server_addr.sin_addr.s_addr = htonl(INADDR_ANY);/* 本地地址 */

server_addr.sin_port = htons(PORT); /* 服务器端口 */

/* 绑定地址结构到套接字描述符 */

err = bind(ss, (struct sockaddr*)&server_addr, sizeof(server_addr));

if(err < 0){/* 出错 */

printf("bind error\n");

return -1;

}

/* 设置侦听 */

err = listen(ss, BACKLOG);

if(err < 0){/* 出错 */

printf("listen error\n");

return -1;

}

/* 主循环过程 */

for(;;) {

int addrlen = sizeof(struct sockaddr);

/* 接收客户端连接 */

sc = accept(ss, (struct sockaddr*)&client_addr, &addrlen);

if(sc < 0){ /* 出错 */

continue; /* 结束本次循环 */

}

/* 建立一个新的进程处理到来的连接 */

pid = fork(); /* 分叉进程 */

if( pid == 0 ){ /* 子进程中 */

close(ss); /* 在子进程中关闭服务器的侦听 */

process_conn_server(sc);/* 处理连接 */

}else{

close(sc); /* 在父进程中关闭客户端的连接 */

}

}

}


client.c

#include

#include

#include

#include

#include

#include

#include

#include


extern void sig_proccess(int signo);

extern void sig_pipe(int signo);

static int s;

void sig_proccess_client(int signo)

{

printf("Catch a exit signal\n");

close(s);

exit(0);

}


#define PORT 8888 /* 侦听端口地址 */

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

{


struct sockaddr_in server_addr; /* 服务器地址结构 */

int err;/* 返回值 */

signal(SIGINT, sig_proccess);

signal(SIGPIPE, sig_pipe);

/* 建立一个流式套接字 */

s = socket(AF_INET, SOCK_STREAM, 0);

if(s < 0){/* 出错 */

printf("socket error\n");

return -1;

}

/* 设置服务器地址 */

bzero(&server_addr, sizeof(server_addr)); /* 清0 */

server_addr.sin_family = AF_INET; /* 协议族 */

server_addr.sin_addr.s_addr = htonl(INADDR_ANY);/* 本地地址 */

server_addr.sin_port = htons(PORT); /* 服务器端口 */

/* 将用户输入的字符串类型的IP地址转为整型 */

inet_pton(AF_INET, argv[1], &server_addr.sin_addr);

/* 连接服务器 */

connect(s, (struct sockaddr*)&server_addr, sizeof(struct sockaddr));

process_conn_client(s); /* 客户端处理过程 */

close(s); /* 关闭连接 */

}



使用函数的文件
process.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>

/* 服务器对客户端的处理 */
void process_conn_server(int s)
{
    ssize_t size = 0;
    char buffer[1024];    /* 数据的缓冲区 */
    char buffer1[1024];
    
    for(;;){/* 循环处理过程 */
        /* 从套接字中读取数据放到缓冲区buffer中 */
        memset(buffer,'\0',sizeof(buffer));
        size = read(s, buffer, 1024);    
        if(size == 0){/* 没有数据 */
            return;    
        }
        
        /* 构建响应字符,为接收到客户端字节的数量 */
        sprintf(buffer1, "%d bytes altogether\n", size);
        write(s, buffer1, strlen(buffer1));/* 发给客户端 */
        printf("message is %s\n",buffer);
    }    
}

/* 客户端的处理过程 */
void process_conn_client(int s)
{
    ssize_t size = 0;
    char buffer[1024];    /* 数据的缓冲区 */
    
    for(;;){/* 循环处理过程 */
        /* 从标准输入中读取数据放到缓冲区buffer中 */
        size = read(0, buffer, 1024);
        if(size > 0){/* 读到数据 */
            write(s, buffer, size);        /* 发送给服务器 */
            size = read(s, buffer, 1024);/* 从服务器读取数据 */
            write(1, buffer, size);        /* 写到标准输出 */
        }
    }    
}

void sig_proccess(int signo)
{
    printf("Catch a exit signal\n");
    exit(0);    
}

void sig_pipe(int sign)
{
    printf("Catch a SIGPIPE signal\n");
    
    /* 释放资源 */    
}


makefile


CC = gcc
all:client server
    
client:process.o client.o
    $(CC) -o client process.o client.o
server:process.o server.o
    $(CC) -o server process.o server.o
clean:
    rm -f client server *.o


编译运行过程:
make后,首先开一个终端运行server:./server
然后开一个终端运行client:./client 192.168.1.88(这里的ip必须是运行server的ip,如果本机测试127.0.0.1也可以)
这个例子参考书上的写的,加的注释比较多,可以在此基础加上自己的想法去体验吧。
阅读(4180) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~