|
|
Регистрация Восстановить пароль |
Повторная активизация e-mail |
Регистрация | Задать вопрос |
Заплачу за решение |
Новые сообщения |
Сообщения за день |
Расширенный поиск |
Правила |
Всё прочитано |
|
Опции темы | Поиск в этой теме |
24.09.2012, 15:38 | #1 |
Пользователь
Регистрация: 24.09.2012
Сообщений: 11
|
Клиент-сервер, потоки, загвоздка в постоянном чтении и отправке сообщений.
Здравствуйте уважаемые программисты, я пытаюсь написать программку для отправки и приёма сообщений(что-то вроде аськи), по средствам соединения сервер - клиент. Загвоздка в том чтобы и клиент и сервер могли одновременно и принимать и отправлять сообщения.
Если сможете напишите какую можно литературу почитать по программированию TCP и потоков, желательно чтобы доступным языком была написана)спасибо. Заранее прошу прощения за быть может глупые ошибки в коде, я лишь начинающий программист) спасибо за понимание. собственно код сервера: #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string> #include <pthread.h> using namespace std; char Message1[300], Message2[300]; int sock; int Client; void * wrt(void * arg); void * rd(void * arg); int main( void ) { char ClientName[30], PCName [30]; struct sockaddr_in serv; // Свойства(адрес) создаваемого сокета gethostname(PCName, 30); int r_bind; int r_listen; int r_read; int r_write; serv.sin_family = AF_INET; serv.sin_port = htons( 7500 ); serv.sin_addr.s_addr = htonl( INADDR_ANY ); sock = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP ); if ( sock < 0 ) { perror( "ошибка вызова socket" ); exit( 1 ) ; } r_bind = bind( sock, ( struct sockaddr * )&serv, sizeof( serv ) ); if ( r_bind < 0 ) { perror( "ошибка вызова bind" ); exit( 1 ); } //Ожидаем клиента printf("Wait of client...\n"); r_listen = listen( sock, SOMAXCONN ); if ( r_listen ) { perror( "ошибка вызова listen" ); exit (1); } Client = accept( sock, NULL , NULL );//( struct sockaddr * )&serv if ( Client < 0 ) { perror ( "ошибка вызова accept" ); exit( 1 ); } r_read = recv( Client, ClientName, 30, 0 ); if ( r_read <= 0 ) { perror( "ошибка вызова recv" ); exit( 1 ); } r_write = send( Client, PCName , 31, 0 ); if ( r_write <= 0 ) { perror( "ошибка вызова send" ); exit( 0 ); } printf("Client ( \" %s \" ) has connected!\n", ClientName); pthread_t thr1, thr2; int id1 = 1; int id2 = 2; int result; result = pthread_create(&thr1, NULL, wrt, &id1); result = pthread_create(&thr2, NULL, rd, &id2); result = pthread_join(thr1, NULL); result = pthread_join(thr2, NULL); // Закрытие сокетов и окончание работы shutdown(sock, 0); close(sock); close(Client); getchar(); return 0; } void * wrt(void * arg) { while(true) { scanf("%299s",Message1); if (send(Client, Message1, 301, 0) != 'q') printf("Sent!\n"); else printf("Error of sending!\n"); } } void * rd(void * arg) { while(true) { if (recv(Client, Message2, 300, 0) != 'q') { printf("\nreading:\t%s\n", Message2); getchar(); } else printf("Error of reading!\n"); } } и код клиента: #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string> #include <pthread.h> using namespace std; char Message1[300],Message2[300]; int sock; void * wrt(void * arg); void * rd(void * arg); int main( void ) { char PCName[30], ServerName[30], IP[16] = { 0 }; struct sockaddr_in clien; int r_connect; int r_read; int r_write; //Ввод IP-адреса сервера printf("Enter server's IP: "); scanf("%15s", IP); gethostname(PCName, 30); // Получение имени текущего ПК clien.sin_family = AF_INET; clien.sin_port = htons( 7500 ); clien.sin_addr.s_addr = inet_addr( IP ); sock = socket( AF_INET, SOCK_STREAM, 0 ); if ( sock < 0 ) { perror( "ошибка вызова socket" ); exit( 1 ); } //Подключение к серверу printf("connecting to server...\n"); r_connect = connect( sock, ( struct sockaddr *)&clien, sizeof( clien ) ); if ( r_connect ) { perror( "ошибка вызова connect" ); exit( 1 ); } r_write = send(sock, PCName, 31, 0 ); if ( r_write <= 0 ) { perror( "ошибка вызова send" ); exit( 1 ); } r_read = recv(sock, ServerName, 30, 0); if ( r_read <= 0 ) perror( "ошибка вызова recv" ); printf("connect to \" %s \" \n", ServerName); pthread_t thr1, thr2; int id1 = 1; int id2 = 2; int result; result = pthread_create(&thr1, NULL, wrt, &id1); result = pthread_create(&thr2, NULL, rd, &id2); result = pthread_join(thr1, NULL); result = pthread_join(thr2, NULL); // Закрытие сокетов и окончание работы с WinSock shutdown(sock, 0); close(sock); getchar(); return 0; } void * wrt(void * arg) { while(true) { scanf("%299s",Message1); if (send(sock, Message1, 301, 0) != 'q') printf("Sent!\n"); else printf("Error of sending!\n"); } } void * rd(void * arg) { while(true) { if (recv(sock, Message2, 300, 0) != 'q') { printf("\nreading:\t%s\n", Message2); getchar(); } else printf("Error of reading!\n"); } } |
25.09.2012, 15:24 | #2 |
Пользователь
Регистрация: 23.11.2011
Сообщений: 49
|
во-первых, вместо инклюда всего по отдельности, половину из ваших инклюдов можно заменить одним
#include <windows.h> (в т.ч. винсокс) во-вторых, вот пример моего клиент-сервер, сервер может держать соединения с больше чем одним клиентом Код:
|
25.09.2012, 15:27 | #3 |
Пользователь
Регистрация: 23.11.2011
Сообщений: 49
|
а вот клиент
Код:
|
25.09.2012, 15:29 | #4 |
Пользователь
Регистрация: 23.11.2011
Сообщений: 49
|
а по литературе
потоки: http://www.realcoding.net/article/view/1749 сокеты(под виндос): http://cs5856.userapi.com/u69125685/...4/WinSock1.pdf |
25.09.2012, 15:41 | #5 |
Старожил
Регистрация: 13.07.2012
Сообщений: 6,331
|
|
25.09.2012, 15:57 | #6 | |
Пользователь
Регистрация: 24.09.2012
Сообщений: 11
|
За ссылочки большое спасибо.
Цитата:
Сервер: pthread_t thr1, thr2; int id1 = 1; int id2 = 2; int result; result = pthread_create(&thr1, NULL, wrt, &id1); result = pthread_create(&thr2, NULL, rd, &id2); result = pthread_join(thr1, NULL); result = pthread_join(thr2, NULL); // Закрытие сокетов и окончание работы shutdown(sock, 0); close(sock); close(Client); getchar(); return 0; } void * wrt(void * arg) { while(true) { scanf("%299s",Message1); if (send(Client, Message1, 301, 0) != EOF) printf("Sent!\n"); else printf("Error of sending!\n"); int r_write = send(sock, Message1, 301, 0); if ( r_write <= 0 ) { perror( "ошибка вызова send" ); exit( 1 ); } } } void * rd(void * arg) { while(true) { int i = recv(Client, Message2, 300, 0); if ( i <= -1 ) { printf("Error of reading!\n"); exit( 1 ); } else printf("reading:\t%s\n", Message2); } } |
|
25.09.2012, 15:57 | #7 |
Пользователь
Регистрация: 24.09.2012
Сообщений: 11
|
И вот злощастный клиент:
pthread_t thr1, thr2; int id1 = 1; int id2 = 2; int result; result = pthread_create(&thr1, NULL, wrt, &id1); result = pthread_create(&thr2, NULL, rd, &id2); result = pthread_join(thr1, NULL); result = pthread_join(thr2, NULL); // Закрытие сокетов и окончание работы shutdown(sock, 0); close(sock); getchar(); return 0; } void * wrt(void * arg) { while(true) { scanf("%299s",Message1); if (send(sock, Message1, 301, 0) != EOF) printf("Sent!\n"); else printf("Error of sending!\n"); int r_write = send(sock, Message1, 301, 0); if ( r_write <= 0 ) { perror( "ошибка вызова send" ); exit( 1 ); } } } void * rd(void * arg) { while(true) { int i = recv(sock, Message2, 300, 0); if ( i <= -1 ) { printf("Error of reading!\n"); exit( 1 ); } else printf("reading:\t%s\n", Message2); } } //Целиком не выкладывал, кроме send и recv ничего не менял Последний раз редактировалось Чиффа; 25.09.2012 в 16:04. |
25.09.2012, 16:03 | #8 |
Пользователь
Регистрация: 24.09.2012
Сообщений: 11
|
кстати так же не могу понять, при чтении сообщения сервер вначале выводит по 1 сообщению приходящему, а потом почему-то по 2 о_О...
на сколько я понял из манов команда recv ожидает прибытия сообщения из сокета, пока то не придёт... соответственно почему такая ерунда с прибытием сообщений на клиент, и почему по 2 сообщения печатает сервер, не понятно =( |
25.09.2012, 17:02 | #9 |
Пользователь
Регистрация: 23.11.2011
Сообщений: 49
|
линукс не моё. даже не знаю чем помочь тогда твой код мне очень не понятен
я бы скинул весь код моего серверклиента, но раз линукс.. ну в общем надо?) |
25.09.2012, 17:05 | #10 |
Пользователь
Регистрация: 24.09.2012
Сообщений: 11
|
Нет, спасибо, буду дальше разбираться... думаю рано или поздно дойдёт как сделать, а потом и как правильно сделать)
|
Похожие темы | ||||
Тема | Автор | Раздел | Ответов | Последнее сообщение |
Как отправить видео захват(с веб-Кам.) Клиент->Сервер->Клиент | RODNOC | Мультимедиа в Delphi | 17 | 03.10.2010 22:31 |
Ошибка при отправке сообщений через SMTPClient | BoT_T | Работа с сетью в Delphi | 6 | 26.09.2010 17:16 |
Возможно-ли Клиент-серверное приложение типа Клиент(Pascal) а сервер(CGI)? | Demol | Работа с сетью в Delphi | 1 | 21.04.2009 16:18 |
Формат передаваемых данных хабам локальной сети, при отправке личных сообщений из DC клиетов | docm | Общие вопросы .NET | 0 | 18.11.2008 15:33 |