Сокеты - C (СИ)
Формулировка задачи:
Написал простой TCP клинет
и TCP сервер
в первый раз когда запустил было все нормально клиент выводил 2 а сервер 1. Но во второй раз сервер вывел 1 а клиент нечего. Как это можно исправить?
сервер
#include <winsock2.h> #include <stdio.h> int main(void) { WORD v=MAKEWORD(2,0); WSADATA d; int e=WSAStartup(v,&d); if (e) { perror("error initializing winsock"); return 1; } struct sockaddr_in peer; int s; int rc; char buf[1]; peer.sin_family=AF_INET; peer.sin_port=htons(7500); peer.sin_addr.s_addr=inet_addr("127.0.0.1"); s=socket(AF_INET,SOCK_STREAM,0); if (s<0) { perror("error calling socket"); return 1; } rc=connect(s,(struct sockaddr *)&peer,sizeof(peer)); if (rc) { perror("error calling connect"); return 1; } rc=send(s,"1",1,0); if (rc<=0) { perror("error calling send"); return 1; } rc=recv(s,buf,1,0); if (recv<=0) perror("error calling recv"); else printf("%c\n",buf[0]); return 0; }
#include <winsock2.h> #include <stdio.h> int main(void) { WORD v=MAKEWORD(2,0); WSADATA d; int e=WSAStartup(v,&d); if (e) { perror("error initializing winsock"); return 1; } struct sockaddr_in local; int s; int s1; int rc; char buf[1]; local.sin_family=AF_INET; local.sin_port=htons(7500); local.sin_addr.s_addr=htonl(INADDR_ANY); s=socket(AF_INET,SOCK_STREAM,0); if (s<0) { perror("error calling socket"); return 1; } rc=bind(s,(struct sockaddr *)&local,sizeof(local)); if (rc<0) { perror("error calling bind"); return 1; } rc=listen(s,5); if (rc) { perror("error calling listen"); return 1; } s1=accept(s,NULL,NULL); if (s1<0) { perror("error calling accept"); return 1; } rc=recv(s1,buf,1,0); if (rc<=0) { perror("error calling recv"); return 1; } printf("%c\n",buf[0]); rc=send(s1,"2",1,0); if (rc<=0) perror("error calling send"); return 0; }
Исправил, оказывается забыл закрыть сокеты. Если кому надо вот исправленные клиент и сервер.
клинет
#include <winsock2.h> #include <stdio.h> int main(void) { WORD v=MAKEWORD(2,0); WSADATA d; int e=WSAStartup(v,&d); if (e) { perror("error initializing winsock"); return 1; } struct sockaddr_in peer; int s; int rc; char buf[1]; peer.sin_family=AF_INET; peer.sin_port=htons(7500); peer.sin_addr.s_addr=inet_addr("127.0.0.1"); s=socket(AF_INET,SOCK_STREAM,0); if (s<0) { perror("error calling socket"); return 1; } rc=connect(s,(struct sockaddr *)&peer,sizeof(peer)); if (rc) { perror("error calling connect"); return 1; } rc=send(s,"1",1,0); if (rc<=0) { perror("error calling send"); return 1; } rc=recv(s,buf,1,0); if (recv<=0) perror("error calling recv"); else printf("%c\n",buf[0]); if (closesocket(s)) perror("error calling closesocket"); WSACleanup(); return 0; }
#include <winsock2.h> #include <stdio.h> int main(void) { WORD v=MAKEWORD(2,0); WSADATA d; int e=WSAStartup(v,&d); if (e) { perror("error initializing winsock"); return 1; } struct sockaddr_in local; int s; int s1; int rc; char buf[1]; local.sin_family=AF_INET; local.sin_port=htons(7500); local.sin_addr.s_addr=htonl(INADDR_ANY); s=socket(AF_INET,SOCK_STREAM,0); if (s<0) { perror("error calling socket"); return 1; } rc=bind(s,(struct sockaddr *)&local,sizeof(local)); if (rc<0) { perror("error calling bind"); return 1; } rc=listen(s,5); if (rc) { perror("error calling listen"); return 1; } s1=accept(s,NULL,NULL); if (s1<0) { perror("error calling accept"); return 1; } rc=recv(s1,buf,1,0); if (rc<=0) { perror("error calling recv"); return 1; } printf("%c\n",buf[0]); rc=send(s1,"2",1,0); if (rc<=0) perror("error calling send"); if (closesocket(s)) perror("error calling closesocket"); if (closesocket(s1)) perror("error calling closesocket"); WSACleanup(); return 0; }
Решение задачи: «Сокеты»
textual
Листинг программы
#include "string.h" #define Q (sockaddr*) #define W send(((SOCKET*)cs)[0],str,strlen(str),0); DWORD WINAPI CLIENT(LPVOID cs); DWORD WINAPI CONEKT(LPVOID ss); int main() { WSADATA wsa; WSAStartup(0x202,&wsa); int n; SOCKET s; sockaddr_in ss; s=socket(AF_INET,SOCK_STREAM,0); ss.sin_family=AF_INET; ss.sin_port=htons(666); ss.sin_addr.s_addr=0; bind(s,Q &ss,sizeof(ss)); listen(s,5); DWORD thID; CreateThread(0,0,CONEKT,&s,0,&thID); label: system("pause"); goto label; return 0; } DWORD WINAPI CONEKT(LPVOID ss) { DWORD thID; SOCKET cs; sockaddr_in css_in; int size_css_in=sizeof(css_in); while((cs=accept(((SOCKET*)ss)[0],Q &css_in,&size_css_in))) CreateThread(0,0,CLIENT,&cs,0,&thID);} DWORD WINAPI CLIENT(LPVOID cs) { char str=0; SOCKET s=((SOCKET*)cs)[0]; timeval tim; fd_set rv; tim.tv_sec=0; tim.tv_usec=100; FD_ZERO(&rv); FD_SET(s,&rv); select(s,&rv,0,0,0); for(;;) { if(FD_ISSET(s,&rv)) { recv(s,&str,1,0); printf("%c",str); } } return 0; }
Объяснение кода листинга программы
- Включается заголовочный файл
string.h
для использования функций работы со строками. - Определяется макрос Q, который преобразует указатель на структуру sockaddr в указатель на первый элемент этой структуры.
- Определяется макрос W, который отправляет данные по сокету.
- Определяются две функции: CLIENT и CONEKT, которые будут использоваться в многопоточной работе.
- В функции main создается дескриптор WSAData для работы с сокетами.
- Создается сокет s и привязывается к порту 666 на localhost.
- Создается поток, который будет прослушивать входящие подключения на сокете s.
- В бесконечном цикле в функции CONEKT принимается каждое входящее подключение и создается новый поток CLIENT для работы с клиентом.
- В функции CLIENT создается сокет s, который передается в функцию accept для принятия входящего подключения.
- В бесконечном цикле в функции CLIENT ожидается приход данных от клиента, которые затем выводятся на экран.
- Все используемые переменные и дескрипторы освобождаются, и программа завершается.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д