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)

浙公网安备 33010602011771号