Skip to content
This repository has been archived by the owner on Sep 9, 2021. It is now read-only.

Морозов Евгений, 3530901/70203 lab1a #73

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
cmake_minimum_required(VERSION 3.0)
project(messenger)
add_executable(client src/client.cpp)
add_executable(server src/server.cpp)
find_library(PH pthread)
target_link_libraries(server ${PH})
target_link_libraries(client ${PH})
126 changes: 126 additions & 0 deletions src/client.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <pthread.h>


#define DEF_PORT 8888
#define DEF_IP "127.0.0.1"
int readFix(int sock, char** buf, char** name, long* time, int flags);
int sendFix(int sock, char* buf, char* name, int flags);
void* reader(void* arg) {
for (;;) {
int sock = *(int *) arg;
char* buf = nullptr;
char* name = nullptr;
time_t time;
int res = readFix(sock, &buf, &name, &time, 0);
if (res <= 0) {
perror("Error while receiving:");
exit(1);
}
time -= timezone;
printf("%s\t%10s:\t%s\n", ctime(&time),name,buf);
free(buf);
free(name);
}
}
int main( int argc, char** argv) {
tzset();
char* addr;
int port;
char* readbuf;
if(argc <3) {
printf("Using default port %d\n",DEF_PORT);
port = DEF_PORT;
} else
port = atoi(argv[2]);
if(argc < 2) {
printf("Using default addr %s\n",DEF_IP);
addr = DEF_IP;
} else
addr = argv[1];
// создаем сокет
struct sockaddr_in peer;
peer.sin_family = AF_INET;
peer.sin_port = htons( port );
peer.sin_addr.s_addr = inet_addr( addr );
int sock = socket( AF_INET, SOCK_STREAM, 0 );
if ( sock < 0 ){
perror( "Can't create socket\n" );
exit( 1 );
}
// присоединяемся к серверу
int res = connect( sock, ( struct sockaddr * )&peer, sizeof(peer ) );
if (res) {
perror( "Can't connect to server:" );
exit( 1 );
}
// основной цикл программы
char buf[100];
char name[20];
printf("Enter your name\n");
bzero(name, 20);
fgets(name, 20, stdin);
name[strlen(name)-1] = '\0';
pthread_t thr;
res = pthread_create(&thr,NULL,reader,(void*)&sock);
if (res) {
printf("Error while creating new thread\n");
}
for(;;) {
printf("Input request (empty to exit)\n");
bzero(buf,100);
fgets(buf, 100, stdin);
buf[strlen(buf)-1] = '\0';
if(strlen(buf) == 0) {
printf("Bye-bye\n");
return 0;
}
res = sendFix(sock, buf, name, 0);
if ( res <= 0 ) {
perror( "Error while sending:" );
exit( 1 );
}

}
}
int readFix(int sock, char** buf, char** name, long* time, int flags) {
// читаем "заголовок" - сколько байт составляет наше сообщение
unsigned msgLength = 0;
unsigned nameLength = 0;
int res=recv(sock,&msgLength,sizeof(unsigned),flags|MSG_WAITALL);
if (res <= 0)return res;
// читаем само сообщение
*buf = new char[msgLength+1];
bzero(*buf, msgLength+1);
res = recv(sock, *buf, msgLength, flags | MSG_WAITALL);
if (res <= 0) return res;
res = recv(sock, &nameLength, sizeof(unsigned), flags | MSG_WAITALL);
if (res <= 0) return res;
*name = new char[nameLength+1];
bzero(*name, nameLength+1);
res = recv(sock, *name, nameLength, flags | MSG_WAITALL);
if (res <= 0) return res;
res = recv(sock, time, sizeof(long), flags | MSG_WAITALL);
if (res <= 0) return res;
return 1;
}
int sendFix(int sock, char* buf, char* name, int flags) {
// число байт в сообщении
unsigned msgLength = strlen(buf);
unsigned nameLength = strlen(name);
int res = send(sock, &msgLength, sizeof(unsigned), flags );
if (res <= 0) return res;
res = send(sock, buf, msgLength, flags);
if (res <= 0) return res;
res = send(sock, &nameLength, sizeof(unsigned), flags);
if (res <= 0) return res;
res = send(sock, name, nameLength, flags);
if (res <= 0) return res;
return 1;
}
133 changes: 133 additions & 0 deletions src/server.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <pthread.h>
#include <set>
#define DEF_PORT 8888
#define DEF_IP "127.0.0.1"
std::set<int> clients;
// обработка одного клиента
int readFix(int sock, char** msg, char** name, long* time, int flags);
int sendFix(int sock, char* buf, char* name, long* time, int flags);
void* clientHandler(void* args) {
int sock = *(int*)args;
char* buf = nullptr;
char* name = nullptr;
int res = 0;
for(;;) {
long time;
res = readFix(sock, &buf,&name, &time, 0);
if ( res <= 0 ) {
perror( "Can't recv data from client, ending thread\n" );
clients.erase(sock);
pthread_exit(nullptr);
}
printf("%s\t%10s:%s\n",ctime(&time),name,buf);
for (auto it = clients.begin(); it != clients.end(); it++) {
res = sendFix(*it, buf,name,&time, 0);
if (res <= 0) {
perror("send call failed");
clients.erase(sock);
pthread_exit(nullptr);
}
}
free(name);
free(buf);
}
}
void* main_cycle(void* args) {
int listener = *(int*)args;
for(;;) {
int client = accept(listener, nullptr, nullptr );
pthread_t thrd;
int res = pthread_create(&thrd, nullptr, clientHandler, (void*)(&client));
if (res){
printf("Error while creating new thread\n");
break;
}
clients.insert(client);
}
}
int main( int argc, char** argv) {
int port = 0;
if(argc < 2) {
printf("Using default port %d\n",DEF_PORT);
port = DEF_PORT;
} else
port = atoi(argv[1]);
struct sockaddr_in listenerInfo;
listenerInfo.sin_family = AF_INET;
listenerInfo.sin_port = htons( port );
listenerInfo.sin_addr.s_addr = htonl( INADDR_ANY );
int listener = socket(AF_INET, SOCK_STREAM, 0 );
if ( listener < 0 ) {
perror( "Can't create socket to listen: " );
exit(1);
}
int res = bind(listener,(struct sockaddr *)&listenerInfo, sizeof(listenerInfo));
if ( res < 0 ) {
perror( "Can't bind socket" );
exit( 1 );
}
// слушаем входящие соединения
res = listen(listener,5);
if (res) {
perror("Error while listening:");
exit(1);
}
// основной цикл работы
pthread_t cycle;
res = pthread_create(&cycle, nullptr, main_cycle, (void*)(&listener));
if (res){
printf("Error while creating new thread\n");
}
char input;
for(;;) {
input = (char)getchar();
if (input == 'q') {
exit(0);
}
}
}
int readFix(int sock, char** msg, char** name, long* time, int flags) {
// читаем "заголовок" - сколько байт составляет наше сообщение
unsigned msgLength = 0;
unsigned nameLength = 0;
struct tm *t;
int res=recv(sock,&msgLength,sizeof(unsigned),flags|MSG_WAITALL );
if (res <= 0)return res;
// читаем само сообщение
*msg = new char[msgLength+1];
bzero(*msg, msgLength+1);
res = recv(sock, *msg, msgLength, flags | MSG_WAITALL);
if (res <= 0) return res;
res = recv(sock,&nameLength, sizeof(unsigned), flags|MSG_WAITALL);
if (res <= 0) return res;
*name= new char[nameLength+1];
bzero(*name, nameLength+1);
res = recv(sock, *name, nameLength, flags|MSG_WAITALL);
if (res <= 0) return res;
*time = ::time(nullptr);
t = gmtime(time);
*time = mktime(t);
return 1;
}
int sendFix(int sock, char* buf, char* name, long* time, int flags) {
// шлем число байт в сообщении
unsigned msgLength = strlen(buf);
unsigned nameLength = strlen(name);
int res = send(sock, &msgLength, sizeof(unsigned), flags );
if (res <= 0) return res;
res = send(sock, buf, msgLength, flags);
if (res <= 0) return res;
res = send(sock, &nameLength, sizeof(unsigned), flags);
if (res <= 0) return res;
res = send(sock, name, nameLength, flags);
if (res <= 0) return res;
res = send(sock, time, sizeof(long), flags);
if (res <= 0) return res;
return 1;
}