/*
* server.c
* Created on: 2008-10-18
* Author: xunzhao
* internet domain 通信,服务器端
*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#include <errno.h>
#include <signal.h>
#include <sys/wait.h>
#include <netdb.h>
#include <stdlib.h>
#include <ctype.h>
#include <arpa/inet.h>
#include <time.h>
#include "usock.h"
#define port 5120 //服务器监听端口
//捕获子进程退出信号,在退出时给出提示信息
void sig_handler(int signo){
pid_t pid;
int stat;
pid = waitpid(-1, &stat, WNOHANG);
while(pid > 0){
printf("Child process terminated (PID: %ld) \n",(long)getpid());
pid = waitpid(-1, &stat, WNOHANG);
}
return ;
}
int main(int argc, char *argv[])
{
int listen_fd,com_fd,ret,on,i;
socklen_t len;
pid_t pid;
time_t timep;
struct tm *echo_time;
char username[30];
static char snd_buf[1024];
static char recv_buf[1024];
//struct sockaddr_in clt_addr;
//struct sockaddr_in srv_addr;
struct usock clt_addr; //usock是我自定义的一个结构体,把原来的sockaddr_in结构体作为usock的一个字段
struct usock srv_addr; //并增加一个用户名字段,
//我的初衷是实现用户第一次连接服务器时就自动发送用户名
time(&timep);
echo_time=localtime(&timep); //获取当地时间
//参数验证
if(argc != 1){
printf("Usage: %s \n", argv[0]);
return 1;
}
//设置信号处理函数,也可以使用sigaction函数
if(signal(SIGCHLD, sig_handler) < 0 ){
perror("Cann't set the signal \n");
return 1;
}
//创建套接字用于服务器的监听
listen_fd = socket(AF_INET,SOCK_STREAM,0);
if(listen_fd < 0){
perror("Cann't creat listening socket!\n");
return 1;
}
on = 1;//实现地址/端口重用,避免出现Address already in use的错误
ret = setsockopt(listen_fd,SOL_SOCKET,SO_REUSEADDR, &on, sizeof(on) );
//设置服务器地址参数
memset(&srv_addr, 0, sizeof(srv_addr));
srv_addr.sockaddr.sin_family = AF_INET;
srv_addr.sockaddr.sin_addr.s_addr = htonl(INADDR_ANY);//填入本机IP地址
srv_addr.sockaddr.sin_port = htons(port);//
//绑定套接字与服务器地址信息
//ret = bind(listen_fd,(struct sockaddr*)&srv_addr, sizeof(srv_addr));
ret=bind(listen_fd,(struct sockaddr*)&srv_addr.sockaddr,sizeof(srv_addr));
if(ret == -1 ){
perror("Cann't bind server socket ! \n");
close(listen_fd);
return 1;
}
//监听指定端口,连接5个客户端
ret = listen (listen_fd,5);
if (ret == -1){
perror("Cann't listen the client connect request! \n");
close(listen_fd);
return 1;
} else
puts("服务器启动成功,等待用户登录!\n");
//对每个连接来的客户端创建一个子进程,单独与其进行通信
//首先调用read函数读取客户端发送过来的信息,
//将其转换成大写后发送回客户端
//当输入"@"时,程序退出
while(1){
len = sizeof(clt_addr.sockaddr);
//printf("This is server ,length of clt_addr is %d \n",len);
com_fd = accept(listen_fd,(struct sockaddr*)&clt_addr.sockaddr, &len);
if(com_fd > 0){
//printf("This is server,com_fd is %d \n",com_fd);
recv(com_fd,username,30,0);//这是我目前采用的获取用户名的方式,客户端连接成功后主动send当前用户名到服务端
//我自定义的usock没能起到预期的作用
}
if(com_fd < 0){
if(errno == EINTR){
//printf("EINTR!\n");
continue;
}else{
perror("Cann't accept client connect request !\n");
close(listen_fd);
return 1;
}
}
time(&timep);
echo_time=localtime(&timep); //获取当地时间
printf("用户%s(%s:%d)于%d:%d:%d 登录\n",username,inet_ntoa(clt_addr.sockaddr.sin_addr),ntohs(clt_addr.sockaddr.sin_port),echo_time->tm_hour,echo_time->tm_min,echo_time->tm_sec);
pid = fork();//创建子进程,我想在此获得子进程的socket描述符并保存成一个列表,以实现客户端之间的互相通
//printf("after fork,the pid is %d",pid);
if (pid < 0 ){
perror("Cannot creat the child process \n");
close(listen_fd);
return 1;
}else if ( pid == 0 ){
//清空缓存并从客户端读取数据
memset(recv_buf,0,1024);
while((len = recv(com_fd,recv_buf,1024,0)) > 0 ) {
recv_buf[len] = '\0';
//printf("Message from com_fd: %d\n",com_fd);//这里我的初衷是输入出子进程的socket描述符,但实际上一直输出"4"
time(&timep);
echo_time=localtime(&timep); //获取当地时间
printf("%s (%d:%d:%d) 说:\n%s",username,echo_time->tm_hour,echo_time->tm_min,echo_time->tm_sec,recv_buf);
if(recv_buf[0] == '@' ){
printf("用户%s退出!\n",username);
break;
}
//数据自动处理,进行大小写转换后发送给客户端,也可以设置为服务器端的用户输入,实现聊天
for (i=0; i<len; i++)
snd_buf[i] = toupper(recv_buf[i]);
snd_buf[len] = '\0';
//发送数据
send(com_fd,snd_buf,len,0);
/*write(STDOUT_FILENO,"Server:",8);
//从键盘读取用户输入的数据,并写入发送缓存snd_buf
memset(snd_buf,0,1024);
len=read(STDIN_FILENO,snd_buf,1024);
snd_buf[len] = '\0';
send(com_fd,snd_buf,len,0);
//这段代码可以实现服务端从键盘读取数据,并发送给客户端,这样就可以自由聊天了
*/
}
close(com_fd);
return 0;
}else
close(com_fd);
}
return 0 ;
}
Linux下Socket编程 聊天软件
4星 · 超过85%的资源 需积分: 12 46 浏览量
2008-10-24
17:51:26
上传
评论 8
收藏 4KB RAR 举报
xl_xunzhao
- 粉丝: 23
- 资源: 20
- 1
- 2
- 3
- 4
- 5
- 6
前往页