- 论坛徽章:
- 0
|
以下是个在linux下类似聊天室的C代码,我想改成既能群聊又能点对点私聊, 再有一个要求是点对点传输的消息希望能选择是TCP还是UDP方式传输
--------------服务端---------------------------
#ifndef __INET_H__
#define __INET_H__
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <sys/time.h>
#include <unistd.h>
#include <sys/time.h>
#define MAX_CLIENT 10
#define READ 0
#define WRITE 1
#define MAX_LINE 1000
#define MAX_NAME 100
#define SETNAME "/name"
#define __SELECT__
#endif
#include <signal.h>
#include <sys/wait.h>
int init_ser( int);
int max( int a, int b)
{
int themax;
if ( a > b) themax = a;
else themax = b;
return themax;
}
void set_name( char *line, char *name)
{
strcpy( name, &line[1]);
sprintf( line, "%s en ligne!\n", name);
}
void add_name( char *line, char *name)
{
char theline[MAX_LINE];
strcpy( theline, name);
strcat( theline, " : " ;
strcat( theline, line);
strcpy( line, theline);
}
int user_free( int user_link[MAX_CLIENT])
{
int i = 0;
while ( ( user_link[i] != 0)&&( i <MAX_CLIENT)) i++;
if ( i == MAX_CLIENT) return( -1);
return( i);
}
void add_sockset( fd_set *sockset, int sockfd, int *user_link, int *userfd)
{
int i;
FD_ZERO( sockset);
FD_SET( sockfd, sockset);
for ( i=0; i <MAX_CLIENT; i++) {
if ( user_link[i] == 1) {
FD_SET( userfd[i], sockset);
}
}
}
int main( void)
{
int sockfd;
int new_sockfd;
int user_link[MAX_CLIENT];
int userfd[MAX_CLIENT];
char username[MAX_CLIENT][MAX_NAME];
char line[MAX_LINE];
int userCount;
unsigned int cli_len;
struct sockaddr_in cli_addr;
FILE *file;
int port;
int length, i, j;
fd_set sockset;
int maxfd = 0;
file = fopen( "config", "r" ;
fgets( line, MAX_LINE, file);
fscanf( file, "%d", &port);
fclose( file);
printf ( "%d \n", port);
sockfd = init_ser( port);
if ( sockfd == 0) {
printf( "Init server socket error\n" ;
fflush( stdout);
exit(1);
} //Socket init done
listen( sockfd, MAX_CLIENT);
cli_len = sizeof( cli_addr);
for ( i = 0; i <MAX_CLIENT; i++) {
user_link[i] = 0;
username[i][0] = '\0';
}
userCount = 0;
FD_ZERO( &sockset);
FD_SET( sockfd, &sockset);
maxfd = max( maxfd, sockfd+1);
for ( ; {
select( maxfd, &sockset, NULL, NULL, NULL);
if ( FD_ISSET( sockfd, &sockset)
&& (userCount = user_free( user_link)) >=0) {
new_sockfd = accept( sockfd, (struct sockaddr*)&cli_addr,
&cli_len);
if ( new_sockfd < 0) {
user_link[userCount] = 0;
printf( "acc error\n" ;
} else {
user_link[userCount] = 1;
userfd[userCount] = new_sockfd;
FD_SET( new_sockfd, &sockset);
maxfd = max( maxfd, new_sockfd+1);
}
} // if userCount >= 0
for ( i=0; i <MAX_CLIENT;i++) {
if ( ( user_link[ i] == 1)
&& (FD_ISSET( userfd[i], &sockset))) {
length = read( userfd[i], line, MAX_LINE);
if ( length == 0) { // socket is closed.
user_link[i] = 0;
username[i][0] = '\0';
FD_CLR( userfd[i], &sockset);
} else if ( length >0) {
line[length] = '\0';
if ( (line[0] == '/')&&(username[i][0] == '\0')) {
set_name( line, username[i]);
} else {
add_name( line, username[i]);
}
for ( j=0; j <MAX_CLIENT; j++) {
if ( (j != i)&&(user_link[j]==1)) {
write( userfd[j], line, strlen( line));
}
}
} // length >0
} // user_link[i] == 1
} // for
add_sockset( &sockset, sockfd, user_link, userfd);
} // for
return 0;
}
int init_ser( int port)
//If success, return sockfd, else return 0
{
int SERV_TCP_PORT;
int sockfd;
struct sockaddr_in serv_addr;
SERV_TCP_PORT = port;
if ( ( sockfd = socket( AF_INET,SOCK_STREAM,0)) <0) {
perror( "socket:" ;
printf( "server:can`t open stream socker.\n" ;
fflush( stdout);
return( 0);
}
bzero( ( char*)&serv_addr, sizeof( serv_addr));
serv_addr.sin_family =AF_INET;
serv_addr.sin_addr.s_addr =htonl( INADDR_ANY);
serv_addr.sin_port =htons( SERV_TCP_PORT);
if ( bind( sockfd, ( struct sockaddr *)&serv_addr,
sizeof( serv_addr)) <0) {
perror( "bind:" ;
printf( "server: can`t bind local address\n" ;
fflush( stdout);
return( 0);
}
return( sockfd); //successful.
}
--------------客户端----------------------------------
//-------------------------client.c------------
#ifndef __INET_H__
#define __INET_H__
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <sys/time.h>
#include <unistd.h>
#include <sys/time.h>
#define MAX_CLIENT 10
#define READ 0
#define WRITE 1
#define MAX_LINE 1000
#define MAX_NAME 100
#define SETNAME "/name"
#define __SELECT__
#endif
#include <signal.h>
#include <ctype.h>
extern int init_cli();
void add_set( fd_set *sockset, int sockfd)
{
FD_ZERO( sockset);
FD_SET( sockfd, sockset);
FD_SET( 0, sockset);
}
int main( void)
{
int sockfd;
int status;
char str[MAX_LINE];
char name[MAX_NAME];
fd_set sockset;
sockfd = init_cli();
if ( sockfd == 0) {
printf( "Init client socket error.\n" ;
fflush( stdout);
exit( 1);
}
add_set( &sockset, sockfd);
fprintf( stdout, " lease input your name:");
fscanf( stdin, "%s", name);
strcpy( str, "/");
strcat( str, name);
write( sockfd, str, strlen( str));
while ( 1) {
select( sockfd+1, &sockset, NULL, NULL, NULL);
if (FD_ISSET( sockfd, &sockset)) {
status = read( sockfd, str, MAX_LINE);
if ( status == 0) exit(0);
str[status] = '\0';
printf( "%s", str);
fflush( stdout);
}
if ( FD_ISSET( 0, &sockset)) {
status = read( 0, str, MAX_LINE);
str[status] = '\0';
if ( str[0] == 'q') {
sprintf( str, "%s leave the room.\n", name);
write( sockfd, str, strlen( str));
close( sockfd);
exit( 0);
}
if ( write( sockfd, str, strlen(str)) != strlen( str) ) {
printf( "Write error\n");
exit(0);
}
}
add_set( &sockset, sockfd);
}
return 1;
}
int init_cli( void)
// Return sockfd if successful, else 0
{
int sockfd;
int SERV_TCP_PORT;
char SERV_HOST_ADDR[MAX_LINE];
FILE *fd;
struct sockaddr_in serv_addr;
fd = fopen( "config", "r");
fgets( SERV_HOST_ADDR, MAX_LINE, fd);
fscanf( fd, "%d", &SERV_TCP_PORT);
fclose( fd);
bzero( (char*)&serv_addr, sizeof( serv_addr));
serv_addr.sin_family =AF_INET;
serv_addr.sin_addr.s_addr =inet_addr( SERV_HOST_ADDR);
serv_addr.sin_port =htons( SERV_TCP_PORT);
if ( ( sockfd = socket( AF_INET,SOCK_STREAM,0)) <0) {
printf( "client:can`t open stream socker.\n");
fflush( stdout);
return( 0);
}
if ( connect( sockfd, ( struct sockaddr *)&serv_addr,
sizeof( serv_addr)) <0) {
printf( "client:can`t connect to server\n");
fflush( stdout);
return( 0);
}
return( sockfd);
}
-----------Config文件---------------------------
127.0.0.1
3350 |
|