15. 4. 2008, 11:25 napsal Yo'Sarin, sekce Škola, přečteno 3381×,
Semestrálka na předmět X36PKO, přenos souborů po síti pomocí protokolu TCP. V článku je zadání + zdrojové kódy.
#include <errno.h>
#include <pthread.h>
#include <stdio.h>
#include <time..h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define ECHOPORT 5566
#define BUFFSIZE 512
#define THREAD_COUNT 2
struct data_t {
int c_sockfd;
int sockfd;
struct data_t * prev;
struct data_t * next;
}
;
struct threads_t {
pthread_t * thread;
struct threads_t * next;
}
;
// mutex zamykajici pohromade soubory
pthread_mutex_t out;
pthread_mutex_t checkConnection;
pthread_cond_t condition = PTHREAD_COND_INITIALIZER;
int freeThreads;
void * writeData(void * data);
// data socketů připravených na zpracování
struct data_t * pendingSockets;
struct data_t * headPointer;
struct threads_t * threadsList;
struct threads_t * threadsListHead;
int main(int argc, char *argv[])
{
system("clear");
pendingSockets = malloc(sizeof(struct data_t));
pendingSockets->next = NULL;
pendingSockets->prev = NULL;
headPointer = pendingSockets;
struct sockaddr_in my_addr, rem_addr;
int rem_addr_length;
int sockfd;
if ((sockfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1)
{
perror("Socket nelze otevrit");
exit(1);
}
bzero(&my_addr, sizeof(my_addr));
my_addr.sin_family = AF_INET;
my_addr.sin_port = htons(ECHOPORT);
if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(my_addr)) == -1)
{
perror("Chyba v bind");
close(sockfd); exit(1);
}
if (listen(sockfd, 5) == -1)
{
perror("Nelze provest listen");
close(sockfd); exit(1);
}
int run = 0;
printf("-----------------------\n");
threadsList = malloc(sizeof(struct threads_t));
threadsList->next = NULL;
threadsListHead = threadsList;
int k;
for (k = 0; k < THREAD_COUNT; k++) {
freeThreads++;
threadsList->next = malloc(sizeof(struct threads_t));
pthread_create(threadsList->thread, NULL, writeData, NULL);
threadsList = threadsList->next;
threadsList->next = NULL;
}
while (1)
{
int c_sockfd;
//printf("Prubeh %i\n", run++);
rem_addr_length=sizeof(rem_addr);
if ((c_sockfd = accept(sockfd, (struct sockaddr *)&rem_addr, &rem_addr_length)) == -1)
{
perror("Nelze prijmout spojeni.");
close(sockfd);
exit(1);
}
if(freeThreads == 0) {
freeThreads++;
threadsList->next = malloc(sizeof(struct threads_t));
pthread_create(threadsList->thread, NULL, writeData, NULL);
threadsList = threadsList->next;
threadsList->next = NULL;
}
pthread_mutex_lock(&checkConnection);
pendingSockets->next = malloc(sizeof(struct data_t));
pendingSockets->next->next = NULL;
pendingSockets->next->c_sockfd = c_sockfd;
pendingSockets->next->sockfd = sockfd;
pendingSockets->next->prev = pendingSockets;
pendingSockets = pendingSockets->next;
pthread_mutex_unlock(&checkConnection);
pthread_cond_signal(&condition);
}
close(sockfd);
}
void * writeData(void * data)
{
while (1) {
freeThreads--;
// vlákno poběží immerwere
//int assigned = -1;
int sockfd, c_sockfd;
//while (assigned == -1) {
//sleep(1);
pthread_cond_wait(&condition, &checkConnection);
pthread_mutex_lock(&checkConnection);
if (headPointer->next != NULL) {
headPointer = headPointer->next;
sockfd = headPointer->sockfd;
c_sockfd = headPointer->c_sockfd;
free(headPointer->prev);
headPointer->prev = NULL;
//assigned = 1;
}
pthread_mutex_unlock(&checkConnection);
//}
char filename[255];
filename[0] = 'r';
filename[1] = 'e';
filename[2] = 'c';
filename[3] = 'i';
filename[4] = 'e';
filename[5] = 'v';
filename[6] = 'e';
filename[7] = 'd';
filename[8] = '/';
filename[9] = '\0';
int place = strlen(filename);
int state;
int mlen;
char buf[BUFFSIZE];
while ((state = (mlen = recv(c_sockfd, buf, 1, 0))) && *buf != '\n' && state != -1) {
filename[place++] = buf[0];
filename[place] = '\0';
}
if (state == -1) {
pthread_mutex_lock(&out);
perror("Nelze prijmout nazev souboru");
close(c_sockfd);
pthread_mutex_unlock(&out);
return 1;
}
int size = 0;
int count = 0;
while ((state = (mlen = recv(c_sockfd, buf, 1, 0))) && *buf != '\n' && state != -1) {
if (buf[0] - (int)'0' > 9 || buf[0] - (int)'0' < 0) continue;
size = size * 10 + buf[0] - (int)'0';
}
if (state == -1) {
pthread_mutex_lock(&out);
perror("Nelze prijmout velikost souboru");
close(c_sockfd);
pthread_mutex_unlock(&out);
return 1;
}
else {
pthread_mutex_lock(&out);
fopen(filename, "wb");
printf("Klient: %i\n", c_sockfd);
printf("Soubor: %s\n", filename);
printf("Velikost: %ib\n", size);
printf("-----------------------\n");
pthread_mutex_unlock(&out);
FILE * file = fopen(filename, "wb");
if (file == NULL) {
pthread_mutex_lock(&out);
printf("Nepodarilo se vytvorit soubor %s.\n", filename);
close(c_sockfd);
pthread_mutex_unlock(&out);
return 1;
}
count = 0;
if ((mlen = recv(c_sockfd, buf, BUFFSIZE, 0)) == -1) {
pthread_mutex_lock(&out);
perror("Chyba pri cteni");
fclose(file);
close(c_sockfd);
pthread_mutex_unlock(&out);
return 1;
}
else while (mlen) {
pthread_mutex_lock(&out);
count += mlen;
int res = fwrite(buf, 1, mlen, file);
if(res != mlen) {
perror("Nepodarilo se ulozit data do souboru");
fclose(file);
close(c_sockfd);
pthread_mutex_unlock(&out);
return 1;
}
else if ((mlen = recv(c_sockfd, buf, BUFFSIZE, 0)) == -1) {
perror("Chyba pri cteni");
fclose(file);
close(c_sockfd);
pthread_mutex_unlock(&out);
return 1;
}
pthread_mutex_unlock(&out);
}
pthread_mutex_lock(&out);
printf("Klient: %i\n", c_sockfd);
printf("Soubor: %s\n", filename);
printf("Prenos dokoncen\n");
printf("-----------------------\n");
pthread_mutex_unlock(&out);
fclose(file);
close(c_sockfd);
}
freeThreads++;
}
}
#include
#include
#include
#include
#define ECHOPORT 5566
#define BUFFSIZE 2048
main(int argc, char *argv[])
{
char buf[BUFFSIZE];
int s, len, off;
struct sockaddr_in sin;
if (argc < 2)
{
printf("pouziti: %s ip_cislo_serveru\n", argv[0]);
exit(1);
}
if ((s = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP)) == -1)
{
perror("nelze vytvorit socket");
exit(1);
}
bzero(&sin, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_port = htons(ECHOPORT);
sin.sin_addr.s_addr = inet_addr(argv[1]);
if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) == -1)
{
perror("nelze connect");
close(s);
exit(1);
}
if (write(s, buf, BUFFSIZE) != BUFFSIZE)
{
perror("chyba pri zapisu");
close(s);
exit(1);
}
off=0;
do
{
if((len=read(s, buf+off, BUFFSIZE-off))<=0)
{
perror("chyba pri cteni");
close(s);
exit(1);
}
printf("len: %i\n", len);
off+=len;
}
while (off!=BUFFSIZE);
printf("%d bytu bylo opakovano serverem\n", off);
close(s);
return 0;
}
Diskusní příspěvky vyjadřují názory diskutujících, nikoli autora článku.
Příspěvky nemající souvislost s článkem a příspěvky jejichž jediným účelem je urážet a nadávat budou po zralé úvaze smazány - uvědomte si, že jste na mém písečku.
#1: TiGR, přidáno: 15. 4. 2008, 15:49
Taky jsi to mohl napsat v jave, kdo se ma v tomhle orientovat :-<
#2: Yo'Sarin, přidáno: 17. 4. 2008, 09:44, web: http://www.yosarin.net
Tos uhodl, já se kvůli jedné semestrálce budu znova šťourat v Javě... Bohatě mi stačí že se sem tam musim šťourat v JavaScriptu.