C语言聊天程序选例

这是在CSDN上一网友贴出来的一小程序,用C语言实现,采用了多路I/O复用的方式实现并发服务器的功能.

    一个服务器接收多个客户端的连接请求,某客户端发出向服务器发送的数据,服务器接收后都转发到其它的客户端,服务器不参与聊天的工作,只是完成了信息的转发功能.

    哎,新浪的编辑器总是把C语言的注释代码给过滤掉,有点不爽!

 

//这是一本数上的例子,和你的功能一样.你的例子要改动的太大,偷懒一下.,下边一共5个文件,你弄好后,直接make就可以了,再把config内的ip和端口改一下运行就可以了
//采取的方式是这样的:server只起个中转作用,多clent连接上后,多个clent可以通过server交谈,server本身不参与交谈.
//用法:在一个终端或则后天提交server后,
//在多个终端分别运行clent交谈即可.

  1 //------------------------------------server.c-----------------------------------------
  2 #include <signal.h>
  3 #include <sys/wait.h>
  4 #include "inet.h"
  5 
  6 int init_ser( int);
  7 int max( int a, int b)
  8 {
  9     int themax;
 10 
 11     if ( a > b) themax = a;
 12     else themax = b;
 13     return themax;
 14 }
 15 
 16 void set_name( char *line, char *name)
 17 {
 18     strcpy( name, &line[1]);
 19     sprintf( line, "%s join the roomn", name);
 20 }
 21 
 22 void  add_name( char *line, char *name)
 23 {
 24     char theline[MAX_LINE];
 25 
 26     strcpy( theline, name);
 27     strcat( theline, " : ");
 28     strcat( theline, line);
 29     strcpy( line, theline);
 30 }
 31 
 32 int user_free( int user_link[MAX_CLIENT])
 33 {
 34         int  i = 0;
 35 
 36         while ( ( user_link[i] != 0)&&( i <MAX_CLIENT)) i++;
 37         if ( i == MAX_CLIENT) return( -1);
 38         return( i);
 39 }
 40 
 41 void  add_sockset( fd_set *sockset, int sockfd, int *user_link, int *userfd)
 42 {
 43     int    i;
 44 
 45     FD_ZERO( sockset);
 46     FD_SET( sockfd, sockset);
 47     for ( i=0; i <MAX_CLIENT; i++) {
 48         if ( user_link[i] == 1) {
 49             FD_SET( userfd[i], sockset);
 50         }
 51     }
 52 }
 53 
 54 int main( void)
 55 {
 56     int            sockfd;
 57     int            new_sockfd;
 58     int            user_link[MAX_CLIENT];
 59     int    userfd[MAX_CLIENT];
 60     char    username[MAX_CLIENT][MAX_NAME];
 61     char    line[MAX_LINE];
 62     int            userCount;
 63     unsigned    int        cli_len;
 64     struct  sockaddr_in            cli_addr;
 65     FILE    *file;
 66     int    port;
 67     int    length, i, j;
 68     fd_set  sockset;
 69     int    maxfd = 0;
 70 
 71     file = fopen( "config", "r");
 72     fgets( line, MAX_LINE, file);
 73     fscanf( file, "%d", &port);
 74     fclose( file);
 75     printf ( "%d n", port);
 76     sockfd = init_ser( port);
 77 
 78     if ( sockfd == 0) {
 79                 printf( "Init server socket errorn");
 80                 fflush( stdout);
 81                 exit(1);
 82         } //Socket init done
 83 
 84     listen( sockfd, MAX_CLIENT);
 85     cli_len = sizeof( cli_addr);
 86     for ( i = 0; i <MAX_CLIENT; i++) {
 87         user_link[i] = 0;
 88         username[i][0] = '';
 89     }
 90     userCount = 0;
 91     FD_ZERO( &sockset);
 92     FD_SET( sockfd, &sockset);
 93     maxfd = max( maxfd, sockfd+1);
 94 
 95     for ( ; ;) {
 96         select( maxfd, &sockset, NULL, NULL, NULL);
 97                 if ( FD_ISSET( sockfd, &sockset)
 98             && (userCount = user_free( user_link)) >=0) {
 99                         new_sockfd = accept( sockfd, (struct sockaddr*)&cli_addr,
100                                 &cli_len);
101                         if ( new_sockfd < 0) {
102                                 user_link[userCount] = 0;
103                 printf( "acc errorn");
104                         } else {
105                                 user_link[userCount] = 1;
106                 userfd[userCount] = new_sockfd;
107                 FD_SET( new_sockfd, &sockset);
108                 maxfd = max( maxfd, new_sockfd+1);
109             }
110         } // if userCount >= 0
111         for ( i=0; i <MAX_CLIENT;i++) {
112             if ( ( user_link[ i] == 1)
113                 && (FD_ISSET( userfd[i], &sockset))) {
114                 length = read( userfd[i], line, MAX_LINE);
115                 if ( length == 0) { // socket is closed.
116                     user_link[i] = 0;
117                     username[i][0] = '';
118                     FD_CLR( userfd[i], &sockset);
119                 } else if ( length >0) {
120                     line[length] = '';
121                     if ( (line[0] == '/')&&(username[i][0] == '')) {
122                         set_name( line, username[i]);
123                     } else {
124                         add_name( line, username[i]);
125                     }
126                     for ( j=0; j <MAX_CLIENT; j++) {
127                         if ( (j != i)&&(user_link[j]==1)) {
128                             write( userfd[j], line, strlen( line));
129                         }
130                     }
131                 } // length >0
132             } // user_link[i] == 1
133         } // for
134         add_sockset( &sockset, sockfd, user_link, userfd);
135         } // for
136     return 0;
137 }
138 
139 int    init_ser( int port)
140 //If success, return sockfd, else return 0
141 {
142 
143         int            SERV_TCP_PORT;
144         int            sockfd;
145         struct  sockaddr_in    serv_addr;
146 
147         SERV_TCP_PORT = port;
148 
149         if ( ( sockfd = socket( AF_INET,SOCK_STREAM,0)) <0) {
150         perror( "socket:");
151                 printf( "server:can`t open stream socker.n");
152                 fflush( stdout);
153                 return( 0);
154         }
155 
156         bzero( ( char*)&serv_addr, sizeof( serv_addr));
157         serv_addr.sin_family      =AF_INET;
158         serv_addr.sin_addr.s_addr =htonl( INADDR_ANY);
159         serv_addr.sin_port        =htons( SERV_TCP_PORT);
160 
161         if ( bind( sockfd, ( struct sockaddr *)&serv_addr,
162                 sizeof( serv_addr)) <0) {
163         perror( "bind:");
164                 printf( "server: can`t bind local addressn");
165                 fflush( stdout);
166                 return( 0);
167         }
168         return( sockfd); //successful.
169 }
170 
171 //-------------------------------------client.c-------------------------------------
172 #include "inet.h"
173 #include <signal.h>
174 #include <ctype.h>
175 
176 extern  int init_cli();
177 
178 void add_set( fd_set *sockset, int sockfd)
179 {
180     FD_ZERO( sockset);
181     FD_SET( sockfd, sockset);
182     FD_SET( 0, sockset);
183 }
184 
185 int main( void)
186 {
187     int     sockfd;
188     int     status;
189     char    str[MAX_LINE];
190     char    name[MAX_NAME];
191 
192     fd_set  sockset;
193 
194     sockfd = init_cli();
195     if ( sockfd == 0) {
196             printf( "Init client socket error.n");
197             fflush( stdout);
198             exit( 1);
199     }
200 
201     add_set( &sockset, sockfd);
202 
203     fprintf( stdout, "Please input your name:");
204     fscanf( stdin, "%s", name);
205     strcpy( str, "/");
206     strcat( str, name);
207     write( sockfd, str, strlen( str));
208 
209     while ( 1) {
210         select( sockfd+1, &sockset, NULL, NULL, NULL);
211         if (FD_ISSET( sockfd, &sockset)) {
212             status = read( sockfd, str, MAX_LINE);
213             if ( status == 0) exit(0);
214             str[status] = '';
215             printf( "%s", str);
216             fflush( stdout);
217         }
218         if ( FD_ISSET( 0, &sockset)) {
219             status = read( 0, str, MAX_LINE);
220             str[status] = '';
221             if ( str[0] == 'q') {
222                 sprintf( str, "%s leave the room.n", name);
223                 write( sockfd, str, strlen( str));
224                 close( sockfd);
225                 exit( 0);
226             }
227             if ( write( sockfd, str, strlen(str)) != strlen( str) ) {
228                 printf( "Write errorn");
229                 exit(0);
230             }
231         }
232         add_set( &sockset, sockfd);
233   }
234   return 1;
235 }
236 
237 int    init_cli( void)
238 // Return sockfd if successful, else 0
239 {
240 
241         int    sockfd;
242         int     SERV_TCP_PORT;
243         char    SERV_HOST_ADDR[MAX_LINE];
244         FILE    *fd;
245         struct  sockaddr_in    serv_addr;
246 
247         fd = fopen( "config", "r");
248         fgets( SERV_HOST_ADDR, MAX_LINE, fd);
249         fscanf( fd, "%d", &SERV_TCP_PORT);
250         fclose( fd);
251 
252         bzero( (char*)&serv_addr, sizeof( serv_addr));
253         serv_addr.sin_family      =AF_INET;
254         serv_addr.sin_addr.s_addr =inet_addr( SERV_HOST_ADDR);
255         serv_addr.sin_port        =htons( SERV_TCP_PORT);
256 
257         if ( ( sockfd = socket( AF_INET,SOCK_STREAM,0)) <0) {
258                 printf( "client:can`t open stream socker.n");
259                 fflush( stdout);
260                 return( 0);
261         }
262 
263         if ( connect( sockfd, ( struct sockaddr *)&serv_addr,
264                 sizeof( serv_addr)) <0) {
265                 printf( "client:can`t connect to servern");
266                 fflush( stdout);
267                 return( 0);
268         }
269         return( sockfd);
270 }
271 
272 
273 //----------------------------------- inet.h ---------------------------------------
274 #ifndef __INET_H__
275 #define __INET_H__
276 
277 #include <stdio.h>
278 
279 #include <stdlib.h>
280 #include <string.h>
281 #include <sys/types.h>
282 #include <sys/socket.h>
283 #include <netinet/in.h>
284 #include <arpa/inet.h>
285 #include <fcntl.h>
286 #include <sys/time.h>
287 #include <unistd.h>
288 #include <sys/time.h>
289 
290 #define MAX_CLIENT              10
291 #define READ            0
292 #define WRITE          1
293 #define MAX_LINE        1000
294 #define MAX_NAME        100
295 #define SETNAME "/name"
296 #define __SELECT__
297 
298 #endif

 


//-----------------------------------------------------config------------------------------
192.168.0.88
3350


//-----------------------------------------Makefile---------------------------------------
BINS=
MBINS=client server

all: $(BINS) $(MBINS)

$(BINS): % : %.o
        $(CC)  -o $@ $ <

$(MBINS): % : %.o
        $(CC)  -o $@ $ <

clean:
        -rm -f *.o $(BINS) $(MBINS)

posted @ 2015-07-01 17:11  ysDu  阅读(273)  评论(0)    收藏  举报