📄 scc.c
字号:
#include <pwd.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/stat.h>
#include <sys/types.h>
#include "global.h"
char *getoptarg = "h:ip:n:";
char *ProgramName = "SCC";
char host[MAXHOST];
char nickname[MAXNAME];
int port = 7006;
/*print the usage of scc*/
static void usage(char *msg)
{
fprintf(stderr, "%s: usage error: %s\n", ProgramName, msg);
fprintf(stderr, "usage:\t%s [-h hostname] [-i] [-p port] [-n nickname]\n", ProgramName);
fprintf(stderr, "\t-h hostname\thostname is the server to connect to.\n");
fprintf(stderr, "\t \tthe default value is the localhost.\n");
fprintf(stderr, "\t-i\tencryption is disable.\n");
fprintf(stderr, "\t-p port\tcause port to be used to connect to on the server.\n");
fprintf(stderr, "\t \tthe default value is the 6667.\n");
fprintf(stderr, "\t-n nickname\tlogin as nickname on the specified host.\n");
fprintf(stderr, "\t \tthe default value is the login name of the user.\n");
exit(0);
}
/*get the user name of the user*/
void get_user_name(char * nickname)
{
struct passwd *pw;
char * User;
/* get the user id */
if (!(pw = getpwuid(getuid()))) {
fprintf(stderr, "%s: your UID isn't in the passwd file.\n",
ProgramName);
exit(1);
}
/* dup the user id*/
if(strlen(pw->pw_name) > MAXHOST*sizeof(char)) {
fprintf(stderr,"Host name is too long.\n");
exit(1);
}
strncpy(nickname,pw->pw_name,MAXNAME);
endpwent();
}
/*handle the command line arguments*/
static void parse_args(int argc,char **argv)
{
int argch;
while ((argch = getopt(argc, argv, getoptarg)) != EOF) {
switch (argch) {
case 'h':
/*the host name is too long*/
if(strlen(optarg) > MAXHOST) {
fprintf(stderr,"Host name is too long.\n");
exit(1);
}
strncpy(host,optarg,MAXHOST);
break;
case 'i':
fprintf(stderr,"encryption disable.\n");
break;
case 'p':
port = atoi(optarg);
break;
case 'n':
/*the nickname is too long*/
if(strlen(optarg) > MAXNAME) {
fprintf(stderr,"Nickname is too long.\n");
exit(1);
}
strncpy(nickname,optarg,MAXNAME);
break;
default:
usage("unrecognized option");
}
}
}
int connectsock(const char *transport )
{
struct hostent *phe; /* pointer to host information entry */
struct servent *pse; /* pointer to service information entry */
struct protoent *ppe; /* pointer to protocol information entry*/
struct sockaddr_in sin; /* an Internet endpoint address*/
int s, type; /* socket descriptor and socket type */
char *service = "scc";
memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_port = port;
/* Map host name to IP address, allowing for dotted decimal */
if ( phe = gethostbyname(host) )
memcpy(&sin.sin_addr, phe->h_addr, phe->h_length);
else if ( (sin.sin_addr.s_addr = inet_addr(host)) == INADDR_NONE ) {
fprintf(stderr,"can't get \"%s\" host entry\n", host);
exit(1);
}
/* Map transport protocol name to protocol number */
if ( (ppe = getprotobyname(transport)) == 0) {
fprintf(stderr,"can't get \"%s\" protocol entry\n", transport);
exit(1);
}
/* Use protocol to choose a socket type */
if (strcmp(transport, "udp") == 0) type = SOCK_DGRAM;
else type = SOCK_STREAM;
/* Allocate a socket */
s = socket(PF_INET, type, ppe->p_proto);
if (s < 0) {
fprintf(stderr,"can't create socket: %s\n",strerror(errno));
exit(1);
}
/* Connect the socket */
if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
fprintf(stderr,"can't connect to %s.%s: %s\n", host, service,strerror(errno));
exit(1);
}
return s;
}
/*handle version handshake here and handle
* too many users error here*/
void handshake(int sevfd)
{
char temp[MAX_MES];
char num[20];
int n,i = 0;
int len;
int j = 0;
int err = 0;
int k,l;
char c;
double scdv = 0;
/*get the first message*/
sem_wait(&full);
sem_wait(&mutex);
strcpy(temp,mess_buffer[mess_out]);
mess_out = (mess_out+1)%MAX_SHOW_BUFF;
sem_post(&mutex);
sem_post(&empty);
/*to see whether the message is a handshake message*/
if(strncmp(temp,"SCD Version:",12)==0) {
k = 12;
l = 0;
while(!isdigit(temp[k]))
k++;
while(temp[k]!='\0')
num[l++] = temp[k++];
num[l] = '\0';
scdv = atof(num);
/*if the server version is lower than 0.2*/
if(scdv < 0.2) {
/*ask the user for continue*/
while(1) {
fprintf(stderr,"The version of the sever is lower than 0.2. No encryption is provided.\nDo you want to continue?(y/n)\n");
c = fgetc(stdin);
if(c == 'y'||c == 'Y')
break;
else if(c == 'n'||c == 'N')
exit(1);
}
}
/*send version message*/
sprintf(temp,"SCC Version: 0.1");
send_mes(temp,sevfd);
} else if(strncmp(temp,"ERR:",4)==0) {
/*handle errors here*/
err = get_int(&temp[4]);
if(err < 0) {
fprintf(stderr,"unknown error message\n");
} else if(err == 101) {
fprintf(stderr,"nickname exists\n");
} else if(err == 104) {
fprintf(stderr,"too many users\n");
} else {
fprintf(stderr,"unknown error message\n");
}
exit(1);
}
}
/*connect the server*/
/*create two thread one to handle the screen and the other is
* to handle the network*/
void TCP_scc()
{
char * arg1 = "test1";
char * arg2 = "test2";
char temp[MAX_MES];
int res;
int s;
pthread_t tid_scr;
pthread_t tid_net;
pthread_attr_t thread_attr;
/*connect here*/
s = connectsock("tcp");
serfd = s;
if((res=pthread_attr_init(&thread_attr)) != 0) {
fprintf(stderr,"Attribute creation fails!\n");
exit(1);
}
if((res=pthread_attr_setdetachstate(&thread_attr,
PTHREAD_CREATE_DETACHED)) != 0) {
fprintf(stderr,"Seting detach attribute fails!\n");
exit(1);
}
if((res=pthread_create(&tid_net,&thread_attr,(void * (*)(void *))receive_mes, (void *)s)) != 0) {
fprintf(stderr,"Creating thread fail!\n");
exit(1);
}
handshake(s);
/*send nickname to the server*/
sprintf(temp,"nickname: %s",nickname);
send_mes(temp,s);
if((res=pthread_create(&tid_scr,NULL/*&thread_attr*/,(void * (*)(void *))thread_screen, NULL)) != 0) {
fprintf(stderr,"Creating thread fail!\n");
exit(1);
}
pthread_join(tid_scr, NULL);
(void)pthread_attr_destroy(&thread_attr);
return;
}
/*initialize the semaphores*/
void init_sem()
{
int res;
if((res = sem_init(&full,0,0))!=0) {
fprintf(stderr,"semaphore initialization fail!\n");
exit(1);
}
if((res = sem_init(&empty,0,MAX_SHOW_BUFF))!=0) {
fprintf(stderr,"semaphore initialization fail!\n");
exit(1);
}
if((res = sem_init(&mutex,0,1))!=0) {
fprintf(stderr,"semaphore initialization fail!\n");
exit(1);
}
}
int main(int argc,char **argv)
{
int res;
get_user_name(nickname);
strcpy(host,"localhost");
parse_args(argc,argv);
init_sem();
fprintf(stderr,"nickname: %s\n",nickname);
fprintf(stderr,"host: %s\n",host);
fprintf(stderr,"port: %d\n",port);
TCP_scc();
exit(0);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -