I am a noob trying to establish an easy UDP connection between a client and a server using Ipv6 and C-Language.
Apparently, the sendto() function is returning 1 (failure), but to be honest I don't really understand it at all.
If someone wants to look at it and help it would be greatly appreciated!
thank you. alex
//Server
#define _CRT_SECURE_NO_WARNINGS
#include <winsock2.h>
#include <stdio.h>
#include <stdlib.h>
#include <in6addr.h>
#include <ws2ipdef.h>
#include <stdlib.h>
#include <sys/types.h>
#include <string.h>
#include <WS2tcpip.h>
#pragma comment(lib, "ws2_32.lib")
int startWinsock(void)
{
WSADATA wsa;
return WSAStartup(MAKEWORD(2, 0), &wsa);
}
#define IN6AADR_ANY_INIT {{{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}}
struct in6_addr anyaddr = IN6AADR_ANY_INIT;
int main()
{
printf("this is the Server. \n \n");
long rc;
int socket_fd;
char buf[256];
char buf2[300];
struct sockaddr_in6 remoteAddr;
int remoteAddrLen = sizeof(struct sockaddr_in6);
struct sockaddr_in6 server_addr, client_addr;
rc = startWinsock();
if (rc != 0)
{
printf("error: startWinsock, error code: %d\n", rc);
return 1;
}
else
{
printf("Winsock started!\n");
}
//UDP Socket creation
socket_fd = socket(AF_INET6, SOCK_DGRAM, 0);
if (socket_fd == INVALID_SOCKET)
{
printf("error creating socket, error code: %d\n", WSAGetLastError());
return 1;
}
else
{
printf("UDP Socket erstellt!\n");
}
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin6_family = AF_INET6;
server_addr.sin6_addr = in6addr_any;
server_addr.sin6_port = htons(50000);
rc = bind(socket_fd, (struct sockaddr *) &server_addr, sizeof(server_addr));
if (rc == SOCKET_ERROR)
{
printf("error: bind, error code: %d\n", WSAGetLastError());
return 1;
}
else
{
printf("Socket bind to Port 50.000 \n");
}
while (1)
{
socklen_t clilen = sizeof(client_addr);
rc = recvfrom(socket_fd, buf, 256, 0, (struct sockaddr *) &client_addr, &clilen);
if (rc == SOCKET_ERROR)
{
printf("Error: recvfrom, error code: %d\n", WSAGetLastError());
return 1;
}
else
{
printf("%d Bytes received!\n", rc);
buf[rc] = '\0';
}
printf("recieved data: %s\n", buf);
//Answer
sprintf(buf2, "Du mich auch %s", buf);
rc = sendto(socket_fd, buf2, strlen(buf2), 0, (struct sockaddr_in6*)&remoteAddr, remoteAddrLen);
if (rc == SOCKET_ERROR)
{
printf("Error: sendto, error code: %d\n", WSAGetLastError());
return 1;
}
else
{
printf("%d Bytes sent!\n", rc);
}
}
return 0;
}
//Client
#define _CRT_SECURE_NO_WARNINGS
#include <winsock2.h>
#include <stdio.h>
#include <stdlib.h>
#include <in6addr.h>
#include <ws2ipdef.h>
#include <stdlib.h>
#include <sys/types.h>
#include <string.h>
#include <WS2tcpip.h>
#pragma comment(lib, "ws2_32.lib")
#define SERVADDR "127.0.0.1"
//"fe80::e7:edbf:1df6:7451%5"
int startWinsock(void)
{
WSADATA wsa;
return WSAStartup(MAKEWORD(2, 0), &wsa);
}
int main()
{
printf("this is the client. \n \n");
long rc;
int socket_fd;
socklen_t clilen;
struct sockaddr_in6 server_addr, client_addr;
char buf[256];
char addrbuf[INET6_ADDRSTRLEN];
rc = startWinsock();
if (rc != 0)
{
printf("error: startWinsock, error code: %d\n", rc);
return 1;
}
else
{
printf("Winsock started!\n");
}
//UDP Socket creation
socket_fd = socket(AF_INET6, SOCK_DGRAM, 0);
if (socket_fd == INVALID_SOCKET)
{
printf("error creating socket, error code: %d\n", WSAGetLastError());
return 1;
}
else
{
printf("UDP Socket created!\n");
}
memset(&server_addr, 0, sizeof(server_addr));
// addr prepatation
server_addr.sin6_family = AF_INET6;
inet_pton(AF_INET6, SERVADDR, &server_addr.sin6_addr);
server_addr.sin6_port = htons(50000);
while (1)
{
printf("insert text: ");
gets(buf);
rc = sendto(socket_fd, buf, strlen(buf), 0, (struct sockaddr *)&server_addr, sizeof(struct sockaddr_in6));
if (rc == SOCKET_ERROR)
{
printf("error: sendto, error code: %d\n", WSAGetLastError());
return 1;
}
else
{
printf("%d Bytes sent!\n", rc);
}
rc = recvfrom(socket_fd, buf, 256, 0, (struct sockaddr *)&client_addr, &clilen);
if (rc == SOCKET_ERROR)
{
printf("error: recvfrom, error code: %d\n", WSAGetLastError());
return 1;
}
else
{
printf("%d Bytes received!\n", rc);
buf[rc] = '\0';
printf("received data: %s\n", buf);
}
}
return 0;
}
Related
Refer to the this. UDP INET server and client can send and receive at same side.
But now I want use unix domain socket. Here are my code:
client:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#define SERVER_PATH "tpf_unix_sock.server"
#define DATA "Hello from client\n"
int main(void)
{
int client_socket, rc;
struct sockaddr_un remote, peer_sock;
char buf[256];
memset(&remote, 0, sizeof(struct sockaddr_un));
/****************************************/
/* Create a UNIX domain datagram socket */
/****************************************/
client_socket = socket(AF_UNIX, SOCK_DGRAM, 0);
if (client_socket == -1) {
// printf("SOCKET ERROR = %d\n", sock_errno());
exit(1);
}
remote.sun_family = AF_UNIX;
strcpy(remote.sun_path, SERVER_PATH);
strcpy(buf, DATA);
printf("Sending data...\n");
rc = sendto(client_socket, buf, strlen(buf), MSG_CONFIRM, (struct sockaddr *) &remote, sizeof(remote));
if (rc == -1) {
close(client_socket);
exit(1);
}
else {
printf("Data sent!\n");
}
int n, len;
len = sizeof(remote);
n = recvfrom(client_socket, buf, sizeof(buf),
0, (struct sockaddr *)&remote,
&len);
buf[n] = '\0';
printf("Server : %s\n", buf);
rc = close(client_socket);
return 0;
}
server:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#define SOCK_PATH "tpf_unix_sock.server"
int main(void){
int server_sock, len, rc;
int bytes_rec = 0;
struct sockaddr_un server_sockaddr, peer_sock;
char buf[256];
memset(&server_sockaddr, 0, sizeof(struct sockaddr_un));
memset(buf, 0, 256);
server_sock = socket(AF_UNIX, SOCK_DGRAM, 0);
if (server_sock == -1){
exit(1);
}
server_sockaddr.sun_family = AF_UNIX;
strcpy(server_sockaddr.sun_path, SOCK_PATH);
len = sizeof(server_sockaddr);
unlink(SOCK_PATH);
rc = bind(server_sock, (struct sockaddr *) &server_sockaddr, len);
if (rc == -1){
// printf("BIND ERROR = %d", sock_errno());
close(server_sock);
exit(1);
}
printf("waiting to recvfrom...\n");
bytes_rec = recvfrom(server_sock, buf, 256, MSG_WAITALL, (struct sockaddr *)&peer_sock, &len);
if (bytes_rec == -1){
// printf("RECVFROM ERROR = %d", sock_errno());
close(server_sock);
exit(1);
}
else {
printf("DATA RECEIVED = %s\n", buf);
}
strcpy(buf, "DATA ckt\0");
printf("Sending data...\n");
sleep(1);
rc = sendto(server_sock, buf, strlen(buf), MSG_CONFIRM, (struct sockaddr *)&peer_sock, sizeof(peer_sock));
printf("Data sent!\n");
close(server_sock);
return 0;
}
And server side print:
waiting to recvfrom...
DATA RECEIVED = Hello from client
Sending data...
Data sent!
client side print:
Sending data...
Data sent!
Then it block at "recvfrom" function.
So is there any way to make it send and receive at same side?
Thanks!
The server receives messages from the client, but when sending back to the client through 3 channels, the sctp_recvmsg function returns -1. Sometimes when I run it works, but it happens every other time. Guys help me figure it out!
The server takes up a free port and displays it for connecting to clients. After that it listens on the socket and waits for a connection from the client. When connected, a separate stream is created which is engaged in customer service. After receiving the message, the stream sends back the received message via three channels to the client.
Server
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netinet/sctp.h>
#include <errno.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <iostream>
#include <thread>
#include <vector>
using namespace std;
vector<thread> threadPool;
void multichatThread(int newsock, int flags)
{
char buffer[512];
printf("Новый клиент!\n");
struct sctp_sndrcvinfo sndrcvinfo; // информация о пересылке
if (sctp_recvmsg(newsock, (void *)buffer, sizeof(buffer), (struct sockaddr *)NULL, 0, &sndrcvinfo, &flags) == -1)
{ // принимаем сообщение от клиента
printf("Error sctp_recvmsg!\n");
return;
}
printf("%s\n", buffer);
int i;
for (i = 0; i < 3; i++)
{ // по всем 3-м потокам отправляем информацию
if (sctp_sendmsg(newsock, (void *)buffer, (size_t)strlen(buffer), NULL, 0, 0, 0, i, 0, 0) == -1)
{ // отправляем клиенту сообщение
int ec = errno;
printf("Error sctp_recvmsg %d - %s!\n", ec, strerror(ec));
return;
}
}
close(newsock); // закрываем связь с клиентом
}
void createServer()
{
struct sockaddr_in server, client;
int sock;
// создание сокета
if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP)) == -1)
{
printf("Error create socket!\n");
return;
}
// структура для сервера
server.sin_family = AF_INET;
server.sin_addr.s_addr = htonl(INADDR_ANY); // локальный адрес
server.sin_port = htons(0); // порт сервера
// связка
if (bind(sock, (struct sockaddr *)&server, sizeof(server)) == -1)
{
printf("Error bind!\n");
return;
}
// настройка канала
struct sctp_initmsg initmsg;
initmsg.sinit_num_ostreams = 3; // входные потоки
initmsg.sinit_max_instreams = 3; // выходные потоки
initmsg.sinit_max_attempts = 2; // максимальное количество попыток
setsockopt(sock, IPPROTO_SCTP, SCTP_INITMSG, &initmsg, sizeof(initmsg));
// объявляем очередь
if (listen(sock, 5) == -1)
{
printf("Error listen!\n");
return;
}
struct sockaddr_in sin;
socklen_t len = sizeof(sin);
if (getsockname(sock, (struct sockaddr *)&sin, &len) == -1)
perror("getsockname");
else
{
printf("Сервер создан!\n");
printf("IP: %s\n", inet_ntoa(sin.sin_addr));
printf("Port: %d\n", ntohs(sin.sin_port));
}
int newsock;
int clnlen = sizeof(client), flags;
while (true)
{
if ((newsock = accept(sock, (struct sockaddr *)&client, (socklen_t *)&clnlen)) == -1)
{
printf("Error accept!\n");
return;
}
thread chatThread(multichatThread, newsock, flags);
chatThread.detach();
threadPool.push_back(move(chatThread));
}
close(sock); // закрываем сокет сервера
}
int main()
{
createServer();
return 0;
}
The client receives the port and connects to the server. Then it sends a message to the server and waits for a response from the server through three channels.
Client
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/sctp.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <netdb.h>
#include <unistd.h>
#include <iostream>
using namespace std;
void connectServer(string ip, uint16_t port)
{
// настройка структуры для сервера
struct sockaddr_in server;
server.sin_addr.s_addr = inet_addr("127.0.0.1");
server.sin_family = AF_INET;
server.sin_port = htons(port);
// создаем сокет
int sock;
if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP)) == -1)
{
printf("Error create!\n");
return;
}
// настройка канала
struct sctp_initmsg initmsg;
memset(&initmsg, 0, sizeof(initmsg));
initmsg.sinit_num_ostreams = 3; // выходные потоки
initmsg.sinit_max_instreams = 3; // входные потоки
initmsg.sinit_max_attempts = 2; // количество попыток
setsockopt(sock, IPPROTO_SCTP, SCTP_INITMSG, &initmsg, sizeof(initmsg));
struct sockaddr_in sin;
socklen_t len = sizeof(sin);
printf("Данные о сокете!\n");
printf("IP: %s\n", inet_ntoa(server.sin_addr));
printf("Port: %d\n", ntohs(server.sin_port));
// соединяемся с сервером
if (connect(sock, (struct sockaddr *)&server, sizeof(server)) == -1)
{
printf("Error connect!\n");
return;
}
// отправка и прием сообщения
char buf[512] = "Hello!";
if (sctp_sendmsg(sock, (void *)buf, (size_t)strlen(buf), NULL, 0, 0, 0, 1 /* номер потока */, 0, 0) == -1)
{
printf("Ошибка отправки пакета к серверу!\n");
return;
}
struct sctp_sndrcvinfo sndrcvinfo;
int i, flags;
char buff[512];
for (i = 0; i < 3; i++)
{ // по 3-м каналам принимаем сообщения
bzero((void *)&buff, sizeof(buff));
if (sctp_recvmsg(sock, (void *)buff, sizeof(buff), (struct sockaddr *)NULL, 0, &sndrcvinfo, &flags) == -1)
{
printf("Ошибка отправки пакета от сервера!\n");
return;
}
printf("Сервер: %s\n", buff);
}
close(sock);
}
int main()
{
string ip;
uint16_t port;
cout << "Введите IP:";
cin >> ip;
cout << "Введите PORT:";
cin >> port;
connectServer(ip, port);
return 0;
}
First, check the errno value on error - it may help.
if (sctp_recvmsg(newsock, (void *)buffer, sizeof(buffer), (struct sockaddr *)NULL, 0, &sndrcvinfo, &flags) == -1)
{
int ec = errno;
printf("Error sctp_recvmsg %d - %s!\n", ec, strerror(ec));
return;
}
i have written a small c-program for an IPv6 server with winsock2.h When I run the program in Visual Studio, I get the following message all the time: recvfrom failed
I just can't find the error in the recvfrom function. Maybe someone can see why my program does not work at this point, thanks! :-)
Best regards,
Ken
#define WIN32_LEAN_AND_MEAN
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#pragma comment(lib, "Ws2_32.lib")
int main(int argc, char* argv[]) {
SOCKET server_socket;
struct sockaddr_in6 server_addr, client_addr;
socklen_t client_len;
char buf[1024];
char clientIP[256];
WSADATA data;
WORD version = MAKEWORD(2, 2);
if (WSAStartup(version, &data) == SOCKET_ERROR) {
printf("WSASStartup failed\n");
WSACleanup();
exit(EXIT_FAILURE);
}
server_socket = socket(AF_INET6, SOCK_DGRAM, 0);
if (server_socket == -1) {
printf("creating socket failed\n");
WSACleanup();
exit(EXIT_FAILURE);
}
else {
printf("creating socket successful\n");
}
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin6_addr = in6addr_any;
server_addr.sin6_family = AF_INET6;
server_addr.sin6_port = htons(5001);
if (bind(server_socket, (const struct sockaddr*) & server_addr,
sizeof(server_addr)) == -1) {
printf("bind socket failed\n");
WSACleanup();
exit(EXIT_FAILURE);
}
else {
printf("bind socket successful\n");
}
while (1) {
memset(&client_addr, 0, sizeof(client_addr));
memset(buf, 0, sizeof(buf));
if (recvfrom(server_socket, (char*)buf, 1024, 0,
(struct sockaddr*) & client_addr,
sizeof(client_addr)) == -1) {
printf("recvfrom failed\n");
WSACleanup();
exit(EXIT_FAILURE);
}
else {
printf("recvfrom successful");
}
printf("%s\n", buf);
printf("IP: %s\n", inet_ntop(AF_INET6, &client_addr.sin6_addr,
clientIP, 256));
}
closesocket(server_socket);
WSACleanup();
return 0;
}
You are misusing recvfrom(). The fromlen parameter expects to receive an int* pointer that points to an int, which on input specifies the byte size of the sockaddr buffer being passed in the from parameter, and on output receives the byte size of the sockaddr written to the from buffer.
There are also some other minor bugs in your code:
WSAStartup() does not return SOCKET_ERROR on failure, it returns an actual error code.
you are ignoring the return value of recvfrom(), which tells you how many bytes were actually written to your buf. You are assuming buf is always null-terminated when passing it to printf("%s"), but that is not guaranteed. You are zeroing out buf to initialize it with null terminators, which is fine if recvfrom() receives a datagram containing less than 1024 bytes. But if it receives a datagram with exactly 1024 bytes than all of your null terminators will be overwritten and there will be no terminator left for printf() to find (if recvfrom() receives a datagram with more than 1024 bytes, it will fail with a WSAEMSGSIZE error, which is not a fatal error but you are treating it as if it were). Rather than rely on any null terminators at all, you can pass the return value of recvfrom() to printf() for the buffer size. No need to waste overhead zeroing out what recvfrom() will overwrite.
Try this instead:
#define WIN32_LEAN_AND_MEAN
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#pragma comment(lib, "Ws2_32.lib")
int main(int argc, char* argv[]) {
SOCKET server_socket;
struct sockaddr_in6 server_addr, client_addr;
int client_len, num_recvd;
char buf[1024];
char clientIP[256];
WSADATA data;
WORD version = MAKEWORD(2, 2);
int errCode = WSAStartup(version, &data);
if (errCode != 0) {
printf("WSAStartup failed, error %d\n", errCode);
WSACleanup();
return EXIT_FAILURE;
}
server_socket = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
if (server_socket == INVALID_SOCKET) {
errCode = WSAGetLastError();
printf("creating socket failed, error %d\n", errCode);
WSACleanup();
return EXIT_FAILURE;
}
printf("creating socket successful\n");
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin6_addr = in6addr_any;
server_addr.sin6_family = AF_INET6;
server_addr.sin6_port = htons(5001);
if (bind(server_socket, (struct sockaddr*) &server_addr, sizeof(server_addr)) == SOCKET_ERROR) {
errCode = WSAGetLastError();
printf("bind socket failed, error %d\n", errCode);
closesocket(server_socket);
WSACleanup();
return EXIT_FAILURE;
}
printf("bind socket successful\n");
while (1) {
client_len = sizeof(client_addr);
num_recvd = recvfrom(server_socket, buf, sizeof(buf), 0, (struct sockaddr*) &client_addr, &client_len);
if (num_recvd == SOCKET_ERROR) {
errCode = WSAGetLastError();
if (errCode != WSAEMSGSIZE) {
printf("recvfrom failed, error %d\n", errCode);
closesocket(server_socket);
WSACleanup();
return EXIT_FAILURE;
}
printf("recvfrom truncated a datagram larger than %u bytes!\n", sizeof(buf));
num_recvd = sizeof(buf);
}
else {
printf("recvfrom successful\n");
}
printf("%.*s\n", num_recvd, buf);
printf("IP: %s\n", inet_ntop(AF_INET6, &client_addr.sin6_addr, clientIP, 256));
}
closesocket(server_socket);
WSACleanup();
return 0;
}
I'm trying to make two-way communication over a TCP socket between server and client on Windows. I've tried using threads, but it doesn't work, and I don't know why.
If I try putting this in the while loop, it waits for the user to type something (because of fgets()) before it prints the next message.
while(1) {
bzero(message, 2000);
if (recv(sock, message, 2000, 0) < 0) {
printf("Connection lost!\n");
getch();
}
else {
strcat(message, "\0");
fprintf(stdout, "%s", message);
};
bzero(client, 2000);
fgets(sednmesg, sizeof(sednmesg), stdin);
strcat(client, sednmesg);
strcat(client, "\0");
send(sock, client, strlen(client), 0);
}
My disastrous attempt with threads:
Server.c:
#include <stdio.h>
#include <winsock.h>
#include <stdlib.h>
#include "stdafx.h"
#include <conio.h>
#include <io.h>
#define bzero(b,len) (memset((b), '\0', (len)), (void) 0)
#pragma comment(lib,"ws2_32.lib") //Winsock Library
char message[4040];
DWORD WINAPI thrd() {
WSADATA wsa;
SOCKET sock, newsock;
int c;
struct sockaddr_in server, client;
char smesg[155];
printf("\nInitialising Winsock...");
if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0)
{
printf("Failed. Error Code : %d", WSAGetLastError());
return 1;
}
printf("Initialised.\n");
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) {
printf("Could not create socket! Error: %d", WSAGetLastError());
return 1;
}
//textcolor(2);
printf("Socket Created!\n");
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons(8989);
//bind
if (bind(sock, (struct sockaddr *)&server, sizeof(server)) == SOCKET_ERROR) {
printf("Bind failed! Error Code: %d", WSAGetLastError());
}
puts("Binded!");
printf("\nNow Listening...\n");
listen(sock, 1);
//Accept!
c = sizeof(struct sockaddr_in);
newsock = accept(sock, (struct sockaddr *)&client, &c);
if (newsock == INVALID_SOCKET) {
printf("Couldn't Accept connection!");
}
printf("Accepted Connection!\n");
u_long iMode = 1;
ioctlsocket(newsock, FIONBIO, &iMode);
Sleep(99);
system("cls");
printf("Writer Thread has been started!");
//char *client_ip = inet_ntoa(client.sin_addr);
//int client_port = ntohs(client.sin_port);
while (1) {
bzero(smesg, sizeof(smesg));
fgets(smesg, sizeof(smesg), stdin);
strcat(smesg, "\0");
send(newsock, smesg, strlen(smesg), 0);
}
}
int main()
{
WSADATA wsa;
FILE * fp;
unsigned long on = 1;
const char *file = "fout.txt";
SOCKET sock, newsock;
int c;
struct sockaddr_in server, client;
char smesg[155];
printf("\nInitialising Winsock...");
if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0)
{
printf("Failed. Error Code : %d", WSAGetLastError());
return 1;
}
printf("Initialised.\n");
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) {
printf("Could not create socket! Error: %d", WSAGetLastError());
return 1;
}
//textcolor(2);
printf("Socket Created!\n");
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons(3939);
//bind
if (bind(sock, (struct sockaddr *)&server, sizeof(server)) == SOCKET_ERROR) {
printf("Bind failed! Error Code: %d", WSAGetLastError());
}
puts("Binded!");
printf("\nNow Listening...\n");
listen(sock, 1);
//Accept!
c = sizeof(struct sockaddr_in);
newsock = accept(sock, (struct sockaddr *)&client, &c);
ioctlsocket(newsock, FIONBIO, &on);
if (newsock == INVALID_SOCKET) {
printf("Couldn't Accept connection!");
}
printf("Accepted Connection!\n");
//char *client_ip = inet_ntoa(client.sin_addr);
//int client_port = ntohs(client.sin_port);
HANDLE thread = CreateThread(NULL, 0, thrd, NULL, 0, NULL);
fp = fopen(file, "r+");
while (1) {
/*
bzero(smesg, sizeof(smesg));
printf("Command: ");
fgets(smesg, 155, stdin);
strcat(smesg, "\0");
send(newsock, smesg, strlen(smesg), 0);
*/
bzero(message, sizeof(message));
recv(newsock, message, 2000, 0);
fprintf(stdout, "%s", message);
fprintf(fp, "%s", message);
}
fclose(fp);
return 0;
}
Client.c:
#include <stdio.h>
#include <winsock.h>
#include <stdlib.h>
#include "stdafx.h"
#include <conio.h>
#define bzero(b,len) (memset((b), '\0', (len)), (void) 0)
#pragma comment(lib,"ws2_32.lib") //Winsock Library
DWORD WINAPI thrd() {
char client[2050] = "Client: ";
WSADATA wsa;
SOCKET sock;
struct sockaddr_in server;
char sednmesg[2000];
printf("\nInitialising Winsock...");
if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0)
{
printf("Failed. Error Code : %d", WSAGetLastError());
getch();
return 1;
}
printf("Initialised.\n");
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) {
printf("Could not create socket! Error: %d", WSAGetLastError());
getch();
return 1;
}
//textcolor(2);
printf("Socket Created!\n");
//ioctlsocket(sock, FIONBIO, &on);
server.sin_addr.s_addr = inet_addr("127.0.0.1");
server.sin_family = AF_INET;
server.sin_port = htons(8989);
//Connect
if (connect(sock, (struct sockaddr *)&server, sizeof(server)) < 0) {
puts("Connect Error");
getch();
return 1;
}
puts("Connected\n");
// If iMode!=0, non-blocking mode is enabled.
u_long iMode = 1;
ioctlsocket(sock, FIONBIO, &iMode);
Sleep(99);
system("cls");
printf("Writer Thread has been started!");
//We'll be running this one on port 8989 if this doesn't work!
while (1) {
bzero(client, 2000);
fgets(sednmesg, sizeof(sednmesg), stdin);
strcat(client, sednmesg);
strcat(client, "\0");
send(sock, client, strlen(client), 0);
}
}
int main(int argc, char *argv[])
{
char *msg = "a";
char client[2050] = "Client: ";
unsigned long on = 1;
int reader;
WSADATA wsa;
int sent = 0;
SOCKET sock;
struct sockaddr_in server;
char message[2000];
char sednmesg[2000];
printf("\nInitialising Winsock...");
if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0)
{
printf("Failed. Error Code : %d", WSAGetLastError());
getch();
return 1;
}
printf("Initialised.\n");
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) {
printf("Could not create socket! Error: %d", WSAGetLastError());
getch();
return 1;
}
//textcolor(2);
printf("Socket Created!\n");
//ioctlsocket(sock, FIONBIO, &on);
server.sin_addr.s_addr = inet_addr("127.0.0.1");
server.sin_family = AF_INET;
server.sin_port = htons(3939);
//Connect
if (connect(sock, (struct sockaddr *)&server, sizeof(server)) < 0) {
puts("Connect Error");
getch();
return 1;
}
puts("Connected\n");
// If iMode!=0, non-blocking mode is enabled.
u_long iMode = 1;
ioctlsocket(sock, FIONBIO, &iMode);
//Creating writer thread.
HANDLE thread = CreateThread(NULL, 0, thrd, NULL, 0, NULL);
while (1) {
bzero(message, 2000);
if (recv(sock, message, 2000, 0) < 0) {
printf("Connection lost!\n");
getch();
}
else {
strcat(message, "\0");
fprintf(stdout, "%s", message);
};
//bzero(client, 2000);
/*
fgets(sednmesg, sizeof(sednmesg), stdin);
strcat(client, sednmesg);
strcat(client, "\0");
send(sock, client, strlen(client), 0);
*/
}
return 0;
}
You don't need to open/connect 2 separate listening ports in order to implementing bi-directional communication. TCP is bi-directional, you only need one connection. However, you are enabling non-blocking socket I/O on both ends, but you are not actually using non-blocking I/O correctly. In particular, you are not handling the WSAEWOULDBLOCK error code at all, which is reported by recv() when there is no data available to read, and by send() when the receiver has too much data to read and cannot receive new data yet.
If you want to use threads, then use separate threads for reading and sending, and forget non-blocking I/O altogether. But make sure you are defining your threads correctly (you thread procedure is missing a required input parameter!).
Try something more like this:
Server.c:
#include "stdafx.h"
#include <stdio.h>
#include <winsock.h>
#include <stdlib.h>
#include <conio.h>
#pragma comment(lib,"ws2_32.lib") //Winsock Library
DWORD WINAPI sendThrd(LPVOID lpParam)
{
SOCKET sock = * (SOCKET*) lpParam;
char smesg[155], *pdata;
int len, ret;
do
{
if (!fgets(smesg, sizeof(smesg), stdin))
break;
len = strlen(smesg);
pdata = smesg;
while (len > 0)
{
ret = send(sock, pdata, len, 0);
if (ret == SOCKET_ERROR)
{
printf("Send failed. Error: %d", WSAGetLastError());
break;
}
pdata += ret;
len -= ret;
}
}
while (true);
shutdown(sock, SD_SEND);
return 0;
}
DWORD WINAPI recvThrd(LPVOID lpParam)
{
SOCKET sock = * (SOCKET*) lpParam;
char smesg[256];
int ret;
FILE *fp = fopen("fout.txt", "w+");
do
{
ret = recv(sock, smesg, sizeof(smesg), 0);
if (ret <= 0)
{
if (ret == 0)
printf("Client disconnected\n");
else
printf("Connection lost! Error: %d\n", WSAGetLastError());
break;
}
printf("%.*s", ret, smesg);
if (fp)
fprintf(fp, "%.*s", ret, smesg);
}
while (true);
if (fp)
fclose(fp);
shutdown(sock, SD_RECEIVE);
return 0;
}
int main()
{
WSADATA wsa;
SOCKET sock, newsock;
int c;
struct sockaddr_in server;
printf("Initializing Winsock...\n");
int ret = WSAStartup(MAKEWORD(2, 2), &wsa);
if (ret != 0)
{
printf("Initialization Failed. Error: %d", ret);
return 1;
}
printf("Initialized.\n");
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sock == INVALID_SOCKET) {
printf("Could not create socket! Error: %d\n", WSAGetLastError());
return 1;
}
//textcolor(2);
printf("Socket Created!\n");
memset(&server, 0, sizeof(server));
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons(3939);
//bind
if (bind(sock, (struct sockaddr *)&server, sizeof(server)) == SOCKET_ERROR) {
printf("Bind failed! Error: %d\n", WSAGetLastError());
closesocket(sock);
return 1;
}
printf("Binded!\n");
// listen
if (listen(sock, 1) == SOCKET_ERROR) {
printf("Listen failed! Error: %d\n", WSAGetLastError());
closesocket(sock);
return 1;
}
printf("Now Listening...\n");
//Accept!
c = sizeof(client);
newsock = accept(sock, (struct sockaddr *)&client, &c);
if (newsock == INVALID_SOCKET) {
printf("Couldn't Accept connection! Error: %d\n", WSAGetLastError());
closesocket(sock);
return 1;
}
//char *client_ip = inet_ntoa(client.sin_addr);
//int client_port = ntohs(client.sin_port);
printf("Accepted Connection!\n");
printf("Starting Reader/Writer Threads...\n");
HANDLE threads[2];
threads[0] = CreateThread(NULL, 0, sendThrd, &newsock, 0, NULL);
threads[1] = CreateThread(NULL, 0, recvThrd, &newsock, 0, NULL);
WaitForMultipleObjects(2, threads, TRUE, INFINITE);
CloseHandle(threads[0]);
CloseHandle(threads[1]);
closesocket(newsock);
closesocket(sock);
return 0;
}
Client.c:
#include "stdafx.h"
#include <stdio.h>
#include <winsock.h>
#include <stdlib.h>
#include <conio.h>
#pragma comment(lib,"ws2_32.lib") //Winsock Library
DWORD WINAPI sendThrd(LPVOID lpParam)
{
SOCKET sock = * (SOCKET*) lpParam;
char smesg[155], *pdata;
int len, ret;
do
{
if (!fgets(smesg, sizeof(smesg), stdin))
break;
len = strlen(smesg);
pdata = smesg;
while (len > 0)
{
ret = send(sock, pdata, len, 0);
if (ret == SOCKET_ERROR)
{
printf("Send failed. Error: %d\n", WSAGetLastError());
break;
}
pdata += ret;
len -= ret;
}
}
while (true);
shutdown(sock, SD_SEND);
return 0;
}
DWORD WINAPI recvThrd(LPVOID lpParam)
{
SOCKET sock = * (SOCKET*) lpParam;
char smesg[256];
int ret;
do
{
ret = recv(sock, smesg, sizeof(smesg), 0);
if (ret <= 0)
{
if (ret == 0)
printf("Server disconnected\n");
else
printf("Connection lost! Error: %d\n", WSAGetLastError());
break;
}
printf("%.*s", ret, smesg);
}
while (true);
shutdown(sock, SD_RECEIVE);
return 0;
}
int main(int argc, char *argv[])
{
WSADATA wsa;
SOCKET sock;
struct sockaddr_in server;
printf("Initializing Winsock...\n");
int ret = WSAStartup(MAKEWORD(2, 2), &wsa);
if (ret != 0)
{
printf("Initialization Failed. Error: %d", ret);
return 1;
}
printf("Initialized.\n");
sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock == INVALID_SOCKET) {
printf("Could not create socket! Error: %d", WSAGetLastError());
getch();
return 1;
}
//textcolor(2);
printf("Socket Created!\n");
memset(&server, 0, sizeof(server));
server.sin_addr.s_addr = inet_addr("127.0.0.1");
server.sin_family = AF_INET;
server.sin_port = htons(3939);
//Connect
if (connect(sock, (struct sockaddr *)&server, sizeof(server)) == SOCKET_ERROR) {
printf("Connect failed! Error: %d", WSAGetLastError());
closesocket(sock);
getch();
return 1;
}
printf("Connected\n");
//Creating reader/writer threads.
printf("Starting Reader/Writer Threads...\n");
HANDLE threads[2];
threads[0] = CreateThread(NULL, 0, sendThrd, &sock, 0, NULL);
threads[1] = CreateThread(NULL, 0, recvThrd, &sock, 0, NULL);
WaitForMultipleObjects(2, threads, TRUE, INFINITE);
CloseHandle(threads[0]);
CloseHandle(threads[1]);
closesocket(sock);
getch();
return 0;
}
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I'm trying to send data from a server to a client whenever the client executes a recv() command. As the code stands right now, I cannot get the client to print any data it receives. I cannot figure out whether something is wrong with my server or client, so any help would be appreciated. Thanks!
client.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netdb.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#define ECHO_PORT 9999
#define BUF_SIZE 4096
int main(int argc, char* argv[])
{
if (argc != 3)
{
fprintf(stderr, "usage: %s <server-ip> <port>",argv[0]);
return EXIT_FAILURE;
}
char buf[BUF_SIZE];
int status, sock, sock2;
struct addrinfo hints;
memset(&hints, 0, sizeof(struct addrinfo));
struct addrinfo *servinfo; //will point to the results
hints.ai_family = AF_INET; //IPv4
hints.ai_socktype = SOCK_STREAM; //TCP stream sockets
hints.ai_flags = AI_PASSIVE; //fill in my IP for me
if ((status = getaddrinfo(argv[1], argv[2], &hints, &servinfo)) != 0)
{
fprintf(stderr, "getaddrinfo error: %s \n", gai_strerror(status));
return EXIT_FAILURE;
}
if ((sock = socket(servinfo->ai_family, servinfo->ai_socktype, servinfo->ai_protocol)) == -1)
{
fprintf(stderr, "Socket failed");
return EXIT_FAILURE;
}
if ((connect(sock, (struct sockaddr *) servinfo->ai_addr, servinfo->ai_addrlen)) != 0)
{
fprintf(stderr, "Connection failed");
return EXIT_FAILURE;
}
if ((sock2 = socket(servinfo->ai_family, servinfo->ai_socktype, servinfo->ai_protocol)) == -1)
{
fprintf(stderr, "Socket failed");
return EXIT_FAILURE;
}
if ((connect(sock2, (struct sockaddr *) servinfo->ai_addr, servinfo->ai_addrlen)) != 0)
{
fprintf(stderr, "Connection failed");
return EXIT_FAILURE;
}
while (1) {
//char msg[BUF_SIZE] = "ashudfshuhafhu";
//char msg[BUF_SIZE];
//fgets(msg, BUF_SIZE, stdin);
//int i = 2;
//if (strlen(msg) == i)
// break;
int bytes_received;
// fprintf(stdout, "Sending %s", msg);
//send(sock, msg , strlen(msg), 0);
if((bytes_received = recv(sock, buf, BUF_SIZE, 0)) > 1)
{
buf[bytes_received] = '\0';
fprintf(stdout, "Received %s", buf);
}
}
freeaddrinfo(servinfo);
close(sock);
return EXIT_SUCCESS;
}
Server.c
#include <netinet/in.h>
#include <netinet/ip.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
#define ECHO_PORT 9999
#define BUF_SIZE 4096
int close_socket(int sock)
{
if (close(sock))
{
fprintf(stderr, "Failed closing socket.\n");
return 1;
}
return 0;
}
int main(int argc, char* argv[])
{
int sock, client_sock;
ssize_t readret;
socklen_t cli_size;
struct timeval tv;
struct sockaddr_in addr, cli_addr;
char buf[BUF_SIZE] = "wetwetwetwetwetwetwetwet";
fd_set readfds, writefds;
fd_set activereadfds, activewritefds;
cli_size = sizeof(&cli_addr);
tv.tv_sec = 5;
tv.tv_usec = 0;
fprintf(stdout, "----- Echo Server -----\n");
/* all networked programs must create a socket */
if ((sock = socket(PF_INET, SOCK_STREAM, 0)) == -1)
{
fprintf(stderr, "Failed creating socket.\n");
return EXIT_FAILURE;
}
addr.sin_family = AF_INET;
addr.sin_port = htons(ECHO_PORT);
addr.sin_addr.s_addr = INADDR_ANY;
/* servers bind sockets to ports---notify the OS they accept connections */
if (bind(sock, (struct sockaddr *) &addr, sizeof(addr)))
{
close_socket(sock);
fprintf(stderr, "Failed binding socket.\n");
return EXIT_FAILURE;
}
if (listen(sock, 5))
{
close_socket(sock);
fprintf(stderr, "Error listening on socket.\n");
return EXIT_FAILURE;
}
FD_ZERO(&readfds);
FD_SET(sock, &activereadfds);
while (1)
{
fprintf(stdout,"in here.\n");
readfds = activereadfds;
writefds = activewritefds;
FD_ZERO(&activereadfds);
FD_ZERO(&activewritefds);
if (select(51, &readfds, &writefds, NULL, &tv) < 0)
{
perror("select");
return EXIT_FAILURE;
}
for (int i = 0; i < 10; ++i)
{
if (FD_ISSET (i, &readfds))
{
if (i == sock)
{
fprintf(stdout, "main loop. \n");
client_sock = accept(sock,
(struct sockaddr *) &cli_addr, &cli_size);
FD_SET(client_sock, &activereadfds);
FD_SET(client_sock, &activewritefds);
if (client_sock < 0)
{
perror("accept");
return EXIT_FAILURE;
}
} else {
fprintf(stdout, "second loop \n");
readret = send(i,buf, strlen(buf),0);
if (readret < 0)
fprintf(stdout, "yay");
}
}
if (FD_ISSET(i, &writefds))
{ fprintf(stdout, "ugh \n");
readret = send(i,buf,BUF_SIZE,0);
//if (readret > 0)
//while((readret = recv(i, buf, BUF_SIZE, 0)) >= 1)
// {
//if (send(i, buf, readret, 0) != readret)
//{
// close_socket(i);
// close_socket(sock);
// fprintf(stderr, "Error sending to client.\n");
// return EXIT_FAILURE;
//}
}
}
}
close_socket(sock);
return EXIT_SUCCESS;
}
Your server is sending only when the socket is ready for reading, and as the client is never sending, the server isn't either. The server send should happen when the client socket turns up in the writefds, although actually this isn't the correct way to use that feature. Really you should just send, and only add into and worry about writefds if send() caused EAGAIN/EWOULDBLOCK.
You could be getting an undetected error in the client:
if((bytes_received = recv(sock, buf, BUF_SIZE, 0)) > 1)
{
buf[bytes_received] = '\0';
fprintf(stdout, "Received %s", buf);
}
This should continue:
else if (bytes_received == 0)
{
fprintf(stdout, "peer disconnected\n");
break;
}
else // < 0: error
{
fprintf(stdout, "recv() error %s\n", strerror(errno));
break;
}
You need to print the actual error like this whenever you get an error from a system call.