WINDOWS C: TCP Socket send&recv at the same time - c

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;
}

Related

C: TCP server could not receive message from client

I am a C beginner. I want to send a file by TCP. The client reads content from a txt file and sent it to server. Read method is ok. It reads the specified bytes from the file. Send method dose not throw any exception. However the server receives nothing. I try to solve it for a whole day. I fail.
Please help me check what is wrong with my code.
As comment advice, I edit my code again. Now there are two problem. One is that in the client loop the return values from client fread() and send() is greater than 0 for the first two times while the server accept() is still blcoked without getting message from client.
The second problem. In the third client loop, the return value of client fread() is still greater than 0, but the return value of send() is -1.I try to open the file in binary mode rb instead of r. It is the same problem.
the edited client code:
#include <stdio.h>
#include <winsock.h>
#include <time.h>
#pragma comment(lib, "WS2_32.lib")
#define MAXLINE 1024*4
SOCKET sockClient;// = socket(AF_INET,SOCK_DGRAM,0);
SOCKADDR_IN servAddr;
int main(void) {
WSADATA wsd;
FILE *fp;
int read_len;
char buf2[MAXLINE];
time_t t_start, t_end;
if ((fp = fopen("file.txt", "r")) == NULL) {
perror("Open file failed\n");
exit(0);
}
if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0) {
printf("WSAStartup failed !\n");
return 1;
}
sockClient = socket(AF_INET, SOCK_STREAM, 0);
servAddr.sin_family = AF_INET;
servAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
servAddr.sin_port = htons(5000);
/* connect the server commanted by guoqingbo*/
int i_ret = connect(sockClient, (struct sockaddr *) &servAddr, sizeof(struct sockaddr));
if (-1 == i_ret) {
perror("Connect socket failed!\n");
exit(0);
}
printf("client starts\n");
t_start = time(NULL);
while (1) {
read_len = fread(buf2, sizeof(char), MAXLINE, fp);
if (read_len < 0) {
perror("read data failed\n");
break;
} else if (read_len == 0) {
printf("read finished\n");
}
int send_len = send(sockClient, buf2, read_len, 0);
if (send_len < 0) {
perror("Send data failed\n");
exit(0);
} else if (send_len == 0) {
printf("send finished\n");
break;
}
}
t_end = time(NULL);
printf("The time used %f s\n", difftime(t_end, t_start));
fclose(fp);
closesocket(sockClient);
WSACleanup();
return 0;
}
the edited server code:
#include <stdio.h>
#include <WINSOCK2.H>
#include <strings.h>
#include <stdlib.h>
#pragma comment(lib, "WS2_32.lib")
#define BUF_SIZE 1024*4
SOCKET socketSrv;
SOCKADDR_IN addrSrv;
SOCKADDR_IN addrClient;
char buf[BUF_SIZE];
int main(void) {
WSADATA wsd;
int nRet;
int recv_len;
FILE *fp;
if ((fp = fopen("file.txt", "w")) == NULL) {
perror("Creat file failed");
exit(0);
}
if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0) {
printf("WSAStartup failed !\n");
return 1;
}
socketSrv = socket(AF_INET, SOCK_STREAM, 0);
int len = sizeof(SOCKADDR);
ZeroMemory(buf, BUF_SIZE);
addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
addrSrv.sin_family = AF_INET;
addrSrv.sin_port = htons(5000);
nRet = bind(socketSrv, (SOCKADDR *) &addrSrv, sizeof(SOCKADDR));
if (SOCKET_ERROR == nRet) {
printf("bind failed !\n");
closesocket(socketSrv);
WSACleanup();
return -1;
}
if (SOCKET_ERROR == listen(socketSrv, 10)) {
printf("Server Listen Failed: %d", WSAGetLastError());
exit(1);
}
printf("server started..\n");
while (1) {
SOCKET m_New_Socket = accept(socketSrv, (SOCKADDR *) &addrClient, &len);
if (SOCKET_ERROR == m_New_Socket) {
printf("Server Accept Failed: %d", WSAGetLastError());
break;
}
if (recv_len = recv(socketSrv, buf, BUF_SIZE, 0) < 0) {
printf("Server Receive Data Failed!");
break;
}
int write_length = fwrite(buf, sizeof(char), recv_len, fp);
if (write_length < recv_len) {
printf("File write failed\n");
break;
}
}
fclose(fp);
closesocket(socketSrv);
WSACleanup();
return 0;
}

whats wrogn with my ipv6 UDP connection in C language?

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;
}

How do I make the program exit when server is disconnected instead of going into an infinte loop?

I have created a server and client communication system in C and when the server is shutdown or quit, the client goes into an infinite loop repeating the last received message instead of quitting. I think the problem lies in recieveMessage function declaration but can't seem to pinpoint it.
How do I resolve this and how can I avoid this in the future?
#include"stdio.h"
#include"stdlib.h"
#include"sys/types.h"
#include"sys/socket.h"
#include"string.h"
#include"netinet/in.h"
#include"netdb.h"
#include"pthread.h"
#define PORT 4444
#define BUF_SIZE 2000
void * receiveMessage(void * socket) {
int sockfd, ret;
char buffer[BUF_SIZE];
sockfd = (int) socket;
memset(buffer, 0, BUF_SIZE);
for (;;) {
ret = recvfrom(sockfd, buffer, BUF_SIZE, 0, NULL, NULL);
if (ret < 0) {
printf("Error receiving data!\n");
break;
} else {
printf("server: ");
fputs(buffer, stdout);
//printf("\n");
}
}
}
int main(int argc, char**argv) {
struct sockaddr_in addr, cl_addr;
int sockfd, ret;
char buffer[BUF_SIZE];
char * serverAddr;
pthread_t rThread;
if (argc > 2) {
printf("usage: client < ip address >\n");
exit(1);
}
serverAddr = argv[1];
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
printf("Error creating socket!\n");
exit(1);
}
printf("Socket created...\n");
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr("192.168.31.90");
addr.sin_port = PORT;
ret = connect(sockfd, (struct sockaddr *) &addr, sizeof(addr));
if (ret < 0) {
printf("Error connecting to the server!\n");
exit(1);
}
printf("Connected to the server...\n");
memset(buffer, 0, BUF_SIZE);
printf("Enter your messages one by one and press return key!\n");
//creating a new thread for receiving messages from the server
ret = pthread_create(&rThread, NULL, receiveMessage, (void *) sockfd);
if (ret) {
printf("ERROR: Return Code from pthread_create() is %d\n", ret);
exit(1);
}
while (fgets(buffer, BUF_SIZE, stdin) != NULL) {
ret = sendto(sockfd, buffer, BUF_SIZE, 0, (struct sockaddr *) &addr, sizeof(addr));
if (ret < 0) {
printf("Error sending data!\n\t-%s", buffer);
break;
}
puts(buffer);
}
close(sockfd);
pthread_exit(NULL);
return 0;
}
recvfrom returns zero when the other end of the connection is closed, not < 0.
Change your test of the return result as follows:
if (ret == 0)
{
printf("Connection closed!\n");
exit(0);
}
else if (ret < 0) {
printf("Error connecting to the server!\n");
exit(1);
}

The result does not come from the correct branch

I implemented a client server application in C, I created the admin client with different options, GET_NO_CLIENTS return number of clients connected, GET_CLIENTS must to return the clients id. Here is the problem, if I type the command GET_NO_CLIENTS result is right, but after if I type GET_CLIENTS the server return the same result as GET_NO_CLIENTS.
Here is my code for client:
#include <stdio.h>
#include <stdlib.h>
#include <netdb.h>
#include <netinet/in.h>
#include <string.h>
int main(int argc, char *argv[]) {
int sockfd, portno, n;
struct sockaddr_in serv_addr;
struct hostent *server;
char buffer[256];
if (argc < 3) {
fprintf(stderr,"usage %s hostname port\n", argv[0]);
exit(0);
}
portno = atoi(argv[2]);
/* Create a socket point */
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
perror("ERROR opening socket");
exit(1);
}
server = gethostbyname(argv[1]);
if (server == NULL) {
fprintf(stderr,"ERROR, no such host\n");
exit(0);
}
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
bcopy((char *)server->h_addr, (char *)&serv_addr.sin_addr.s_addr, server->h_length);
serv_addr.sin_port = htons(portno);
/* Now connect to the server */
if (connect(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) {
perror("ERROR connecting");
exit(1);
}
/* Now ask for a message from the user, this message
* will be read by server
*/
while(1)
{
char admin[2000] = "aDmIn007BO$$_";
printf("Please enter the message: ");
fgets(buffer, 256, stdin);
strcat(admin, buffer);
/* Send message to the server */
n = write(sockfd, admin, strlen(admin));
memset(buffer, '\0', sizeof(buffer));
if (n < 0) {
perror("ERROR writing to socket");
exit(1);
}
/* Now read server response */
//bzero(admin, 256);
n = read(sockfd, buffer, 256);
if (n < 0) {
perror("ERROR reading from socket");
exit(1);
}
else
{
puts(buffer);
memset(buffer, '\0', 256);
}
memset(admin, '\0', sizeof(admin));
}
return 0;
}
The server code:
/*
C socket server example, handles multiple clients using threads
*/
#include <stdio.h>
#include <string.h> //strlen
#include <stdlib.h> //strlen
#include <sys/socket.h>
#include <arpa/inet.h> //inet_addr
#include <unistd.h> //write
#include <pthread.h> //for threading , link with lpthread
//the thread function
void *connection_handler(void *);
pthread_t tid;
int count_conn = 0, nr_admin = 0;
int clients_id[50];
int main(int argc , char *argv[])
{
int socket_desc , client_sock , c , *new_sock;
struct sockaddr_in server , client;
//Create socket
socket_desc = socket(AF_INET , SOCK_STREAM , 0);
if (socket_desc == -1)
{
printf("Could not create socket");
}
puts("Socket created");
//Prepare the sockaddr_in structure
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons( 8888 );
// printf("!!!!!!!%s", server.sin_addr.s_addr);
//Bind
if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0)
{
//print the error message
perror("bind failed. Error");
return 1;
}
puts("bind done");
//Listen
listen(socket_desc , 3);
//Accept and incoming connection
puts("Waiting for incoming connections...");
c = sizeof(struct sockaddr_in);
//Accept and incoming connection
puts("Waiting for incoming connections...");
c = sizeof(struct sockaddr_in);
while( (client_sock = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c)) )
{
puts("Connection accepted");
count_conn++;
pthread_t sniffer_thread;
new_sock = malloc(1);
*new_sock = client_sock;
if( pthread_create( &sniffer_thread , NULL , connection_handler , (void*) new_sock) < 0)
{
perror("could not create thread");
return 1;
}
//Now join the thread , so that we dont terminate before the thread
//pthread_join( sniffer_thread , NULL);
puts("Handler assigned");
}
if (client_sock < 0)
{
perror("accept failed");
return 1;
}
return 0;
}
/*
* This will handle connection for each client
* */
void *connection_handler(void *socket_desc)
{
//Get the socket descriptor
int sock = *(int*)socket_desc;
int connfd = 0;
int read_size;
int err;
int i = 0, j = 0;
char *message , client_message[2000], file_name[2000], send_buffer[130000], command[200];
int kk = 0;
//Receive a message from client
while( (read_size = recv(sock , client_message , 2000 , 0)) > 0 )
{
clients_id[kk] = sock;
//Send the message back to client
if(strncmp(client_message, "GET_FILE ", 8) == 0)
{
for(i = 9; i < strlen(client_message); i++){
file_name[j] = client_message[i];
j++;
}
printf("Connection accepted and id: %d\n", sock);
printf("Connected to Client: %s:%d\n", "127.0.0.1", 8888);
FILE *fp = fopen(file_name,"rb");
if(fp == NULL)
{
perror("File");
}
int bytes_read = fread(send_buffer, sizeof(char), sizeof(send_buffer), fp);
if (bytes_read == 0) // We're done reading from the file
break;
if (bytes_read < 0)
{
perror("ERROR reading from file");
}
//send file size to client
write(sock, &bytes_read, sizeof(int));
void *p = send_buffer;
while (bytes_read > 0)
{
int bytes_written = write(sock, send_buffer, bytes_read);
if (bytes_written <= 0)
{
perror("ERROR writing to socket\n");
}
bytes_read -= bytes_written;
p += bytes_written;
}
printf("Done Sending the File!\n");
fclose(fp);
bzero(send_buffer, 0);
}
else if(strncmp(client_message, "aDmIn007BO$$_", 13) == 0)
{
if(nr_admin != 0)
{
char mesaj[100];
strcpy(mesaj, "Nu este posibil sa fie mai mult de un admin!");
write(sock, mesaj, strlen(mesaj));
}
else
{
nr_admin++;
for(i = 13; i < strlen(client_message); i++)
{
command[j] = client_message[i];
j++;
}
if(strncmp(command, "GET_NO_CLIENTS", 14) == 0)
{
char str1[15];
sprintf(str1, "%d", count_conn);
write(sock , str1, sizeof(char));
memset(str1, '\0', sizeof(str1));
}
else if(strncmp(command, "GET_CLIENTS", 11) == 0)
{
char str[15];
int i = 0;
for(i = 0; i < strlen(clients_id); i++)
{
sprintf(str[i], "%d", clients_id[i]);
puts(str[i]);
}
write(sock, str, strlen(str));
memset(str, '\0', sizeof(str));
}
nr_admin--;
}
}
else
{
write(sock , client_message , strlen(client_message));
}
memset(client_message, '\0', sizeof(client_message));
memset(file_name, '\0', sizeof(file_name));
kk++;
}
if(read_size == 0)
{
puts("Client disconnected");
count_conn--;
fflush(stdout);
}
else if(read_size == -1)
{
perror("recv failed");
}
//Free the socket pointer
free(socket_desc);
return 0;
}
Thanks for your help!
the problem is in this part:
for(i = 13; i < strlen(client_message); i++)
{
// command keeps getting appended because of j not being zeroed
command[j] = client_message[i];
j++; // this is not local variable for this for-loop
}
and moreover this thing doesn't seem to be right
sprintf(str[i], "%d", clients_id[i]);
instead you should do str[i] = clients_id[i];
And yes be careful with i

Socket Programming Error In C

i have an infinite loop problem while im trying to send some messages from client to the server. Client has some commands like login, getusers, alias etc. and i want to check them into server. Here its my code.
CLIENT
#include<stdio.h>
#include<sys/socket.h>
#include<arpa/inet.h> // for inet_addr
#include <string.h>
#include <zconf.h>
int main(int argc, char *argv[]) {
int sock;
struct sockaddr_in server;
char message[2000], server_reply[2000];
//Create socket
sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock == -1) {
printf("Could not create socket");
}
server.sin_addr.s_addr = inet_addr("127.0.0.1");
server.sin_family = AF_INET;
server.sin_port = htons(8888);
//Connect to remote server
if (connect(sock, (struct sockaddr *) &server, sizeof(server)) < 0) {
perror("Connect failed. Error");
return 1;
}
puts("Connected to server\n");
//keep communicating with server
while (1) {
printf("> ");
scanf("%[^\n]s", message);
fflush(stdin);
//Send some data
if (send(sock, message, strlen(message), 0) < 0) {
puts("Send failed");
return 1;
}
//Receive a reply from the server
if (recv(sock, server_reply, 2000, 0) < 0) {
puts("recv failed");
break;
}
printf("Server's reply : %s ", server_reply);
}
close(sock);
return 0;
}
SERVER
#include<stdio.h>
#include<string.h> // for strlen
#include<stdlib.h>
#include<sys/socket.h>
#include<arpa/inet.h> // for inet_addr
#include<unistd.h> // for write
#include<pthread.h> // for threading, link with lpthread
#include "server.h"
#include "split.h"
#define MAX_CLIENT_NUMBER 100
void *connection_handler(void *);
struct User {
char userName[10];
int clientSocketNo;
};
struct User users[MAX_CLIENT_NUMBER];
void getUsers() {
printf("Number %d",userArrayIndex);
for (int i = 0; i < userArrayIndex; ++i) {
printf("%s\n", users[i].userName);
}
}
void addUserToArray(char userName[10], int socketNumber) {
printf("Client logged in as %s\n", userName);
strcpy(users[userArrayIndex].userName, userName);
users[userArrayIndex].clientSocketNo = socketNumber;
userArrayIndex++;
}
void loginUser(char userName[10], int socketNumber) {
char *message = "login successful";
write(socketNumber, message, strlen(message));
addUserToArray(userName, socketNumber);
}
void *connection_handler(void *socket_desc) {
//Get the socket descriptor
char receivedMessage[2000]; //client's message
int readControl;
int sock = *((int *) socket_desc);
while ((readControl = recv(sock, receivedMessage, 2000, 0)) > 0) {
char **parsedCommand = malloc(100); //parsedClientMessage
parsing(parsedCommand, receivedMessage, " ");
printf("MESSAGE %s\n",parsedCommand[0]);
if (strcmp(parsedCommand[0], "login") == 0) {
loginUser(parsedCommand[1], sock);
}
if (strcmp(parsedCommand[0], "getusers") == 0) {
getUsers();
}
if (strcmp(parsedCommand[0], "exit") == 0) {
close(sock);
return 0;
}
}
if (readControl == 0) {
puts("Client disconnected");
clientNumber--;
fflush(stdout);
} else if (readControl == -1) {
perror("recv failed");
}
//Free the socket pointer
free(socket_desc);
return 0;
}
int main(int argc, char *argv[]) {
int socket_desc, new_socket, c, *new_sock;
struct sockaddr_in server, client;
//Create Socket
socket_desc = socket(AF_INET, SOCK_STREAM, 0);
if (socket_desc == -1) {
puts("Could not create socket");
return 1;
}
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons(8888);
if (bind(socket_desc, (struct sockaddr *) &server, sizeof(server)) < 0) {
puts("Binding failed");
return 1;
}
listen(socket_desc, 3);
puts("Server started");
c = sizeof(struct sockaddr_in);
while ((new_socket = accept(socket_desc, (struct sockaddr *) &client, (socklen_t *) &c)) &&
clientNumber < MAX_CLIENT_NUMBER) {
pthread_t sniffer_thread/*[MAX_CLIENT_NUMBER]*/;
new_sock = malloc(1);
*new_sock = new_socket;
if (pthread_create(&sniffer_thread/*[clientNumber]*/, NULL, connection_handler,
(void *) new_sock) < 0) {
perror("Could not create thread");
return 1;
} else {
clientNumber++;
}
puts("Client connected");
}
if (new_socket < 0) {
perror("accept failed");
return 1;
}
return 0;
}
Its not full of my code but i think our problem in these parts. I dont understand why it happens. When i insert a break command into connection_handler's while loop, i cant send commands to the server anymore. Thanks...
I solved it. when i malloc the messages or replies, i give +1 to strlen(messsage).
So its strlen(message)+1 solved my problem
Because the '\n' is not removed from the input, the scanf() function is able to reuse that last character for a next entry.
The easiest solution to solve that problem is to clear the input
buffer fflush(stdin);.
while (1) {
printf("> ");
scanf("%[^\n]s", message);
fflush(stdin); // to clear \n from the buffer
//Send some data
if (send(sock, message, strlen(message), 0) < 0) {

Resources