java linux 通信_Linux下TCP通信简单实例

#include

#include

#include

#include

#include

#include

#include

//#include

#include

//#include

#include

#include

/**

关于 sockaddr  sockaddr_in  socketaddr_un说明

http://maomaozaoyue.blog.sohu.com/197538359.html

*/

#define PORT    11910   //定义通信端口

#define BACKLOG 5       //定义侦听队列长度

#define buflen  1024

void process_conn_server(int s);

void sig_pipe(int signo);

int ss,sc;  //ss为服务器socket描述符,sc为某一客户端通信socket描述符

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

{

struct sockaddr_in server_addr; //存储服务器端socket地址结构

struct sockaddr_in client_addr; //存储客户端 socket地址结构

int err;    //返回值

pid_t pid;  //分叉进行的ID

/*****************socket()***************/

ss = socket(AF_INET,SOCK_STREAM,0); //建立一个序列化的,可靠的,双向连接的的字节流

if(ss<0)

{

printf("server : server socket create error\n");

return -1;

}

//注册信号

sighandler_t ret;

ret = signal(SIGTSTP,sig_pipe);

if(SIG_ERR == ret)

{

printf("信号挂接失败\n");

return -1;

}

else

printf("信号挂接成功\n");

/******************bind()****************/

//初始化地址结构

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(PORT);

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

if(err<0)

{

printf("server : bind error\n");

return -1;

}

/*****************listen()***************/

err = listen(ss,BACKLOG);   //设置监听的队列大小

if(err < 0)

{

printf("server : listen error\n");

return -1;

}

/****************accept()***************/

/**

为类方便处理,我们使用两个进程分别管理两个处理:

1,服务器监听新的连接请求;2,以建立连接的C/S实现通信

这两个任务分别放在两个进程中处理,为了防止失误操作

在一个进程中关闭 侦听套接字描述符 另一进程中关闭

客户端连接套接字描述符。注只有当所有套接字全都关闭时

当前连接才能关闭,fork调用的时候父进程与子进程有相同的

套接字,总共两套,两套都关闭掉才能关闭这个套接字

*/

for(;;)

{

socklen_t addrlen = sizeof(client_addr);

//accept返回客户端套接字描述符

sc = accept(ss,(struct sockaddr *)&client_addr,&addrlen);  //注,此处为了获取返回值使用 指针做参数

if(sc < 0)  //出错

{

continue;   //结束此次循环

}

else

{

printf("server : connected\n");

}

//创建一个子线程,用于与客户端通信

pid = fork();

//fork 调用说明:子进程返回 0 ;父进程返回子进程 ID

if(pid == 0)        //子进程,与客户端通信

{

close(ss);

process_conn_server(sc);

}

else

{

close(sc);

}

}

}

/**

服务器对客户端连接处理过程;先读取从客户端发送来的数据,

然后将接收到的数据的字节的个数发送到客户端

*/

//通过套接字 s 与客户端进行通信

void process_conn_server(int s)

{

ssize_t size = 0;

char buffer[buflen];  //定义数据缓冲区

for(;;)

{

//等待读

for(size = 0;size == 0 ;size = read(s,buffer,buflen));

//输出从客户端接收到的数据

printf("%s",buffer);

//结束处理

if(strcmp(buffer,"quit") == 0)

{

close(s);   //成功返回0,失败返回-1

return ;

}

sprintf(buffer,"%d bytes altogether\n",size);

write(s,buffer,strlen(buffer)+1);

}

}

void sig_pipe(int signo)

{

printf("catch a signal\n");

if(signo == SIGTSTP)

{

printf("接收到 SIGTSTP 信号\n");

int ret1 = close(ss);

int ret2 = close(sc);

int ret = ret1>ret2?ret1:ret2;

if(ret == 0)

printf("成功 : 关闭套接字\n");

else if(ret ==-1 )

printf("失败 : 未关闭套接字\n");

exit(1);

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值