Socket Programming in C - Sending a file from Server to Client - c

I have socket code and client code below. So far all that it does is establish connection with the server, but I want it to also send a file from the client to the server; even if the file has no data in it. What do I have to do to augment this code to send files? Any suggestions in code form?
Client:
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <arpa/inet.h>
int main(int argc, char *argv[])
{
int sockfd = 0, n = 0;
char recvBuff[1024];
struct sockaddr_in serv_addr;
if(argc != 2)
{
printf("\n Usage: %s <ip of server> \n",argv[0]);
return 1;
}
memset(recvBuff, '0',sizeof(recvBuff));
if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
printf("\n Error : Could not create socket \n");
return 1;
}
memset(&serv_addr, '0', sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(5000);
if(inet_pton(AF_INET, argv[1], &serv_addr.sin_addr)<=0)
{
printf("\n inet_pton error occured\n");
return 1;
}
if( connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
{
printf("\n Error : Connect Failed \n");
return 1;
}
while ( (n = read(sockfd, recvBuff, sizeof(recvBuff)-1)) > 0)
{
recvBuff[n] = 0;
if(fputs(recvBuff, stdout) == EOF)
{
printf("\n Error : Fputs error\n");
}
}
if(n < 0)
{
printf("\n Read error \n");
}
return 0;
}
Server:
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <time.h>
int main(int argc, char *argv[])
{
int listenfd = 0, connfd = 0;
struct sockaddr_in serv_addr;
char sendBuff[1025];
time_t ticks;
listenfd = socket(AF_INET, SOCK_STREAM, 0);
memset(&serv_addr, '0', sizeof(serv_addr));
memset(sendBuff, '0', sizeof(sendBuff));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(5000);
bind(listenfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
listen(listenfd, 10);
while(1)
{
connfd = accept(listenfd, (struct sockaddr*)NULL, NULL);
ticks = time(NULL);
snprintf(sendBuff, sizeof(sendBuff), "%.24s\r\n", ctime(&ticks));
write(connfd, sendBuff, strlen(sendBuff));
close(connfd);
sleep(1);
}
}

I havn't tried compiling this, and this code is certainly not polished but something similar to below will do the trick :)
Modify the client end to look like this:
if( connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
{
printf("\n Error : Connect Failed \n");
return 1;
}
FILE *inputFile = fopen("inputFile.txt", "rb");
if(inputFile == NULL)
{
fprintf(stderr, "oh no!");
return 1;
}
char sendBuffer[10];
// TODO: Check for errors here
int bytesRead = fread(sendBuffer, sizeof(sendBuffer), 1, inputFile);
while(!feof(inputFile))
{
//TODO: check for errors here
send(sockfd, sendBuffer, bytesRead, 0);
bytesRead = fread(sendBuffer, sizeof(sendBuffer), 1, inputFile);
}
close(sockfd);
Modify the server end to look like this:
listen(listenfd, 10);
FILE *outputFile = fopen("output.txt", "wb");
if(outputFile == null)
{
fprintf(stderr, "Something went south!");
return 1;
}
while(1)
{
connfd = accept(listenfd, (struct sockaddr*)NULL, NULL);
char recvBuff[10];
ticks = time(NULL);
int bytesReceived = recv(confd, recvBuff, 10, 0);
while(bytesReceived != 0)
{
// you should add error checking here
fwrite(recvBuff, bytesReceived, 1, outputFile);
bytesReceived = recv(confd, recvBuff, 10, 0);
}
close(connfd);
}

Related

Problems sending messages to a server using TCP sockets

I'm trying to send messages to a server, but when I connect, the server immediately fails receiving the message. It seems that the server "does not wait" for the user to type the message. The server is supposed to remain in that while loop, forever waiting for clients and printing their messages.
I have no idea what's wrong.
Server code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <dirent.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <pthread.h>
#define PORT 4000
#define WORD_SIZE 256
#define USER_SOCKETS 2
#define MAX_USERS 10
int receiveMessage(int socket, char message[])
{
int bytesReceived;
while (1)
{
bytesReceived = recv(socket, message, WORD_SIZE, 0);
if (bytesReceived < 0)
return -1;
if (bytesReceived == 0)
return 0;
}
}
int main(int argc, char *argv[])
{
int serverSockfd;
socklen_t clilen;
struct sockaddr_in serv_addr, cli_addr;
if ((serverSockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
printf("Error creating the socket.\n");
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(PORT);
serv_addr.sin_addr.s_addr = INADDR_ANY;
bzero(&(serv_addr.sin_zero), 8);
if (bind(serverSockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
{
printf("Error binding the socket..\n");
return -1;
}
if (listen(serverSockfd, 5) < 0)
{
printf("Error on listening.\n");
return -1;
}
int newSockfd;
while (1)
{
if (newSockfd = accept(serverSockfd, (struct sockaddr *)&cli_addr, &clilen) < 0)
{
printf("Error on accept a new client.\n");
continue;
}
char username[WORD_SIZE];
if (receiveMessage(newSockfd, username) < 0)
{
printf("Error receiving message.\n");
close(newSockfd);
}
printf("Message: %s\n", username);
close(newSockfd);
}
return 0;
}
Client code:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#define PORT 4000
int main(int argc, char * argv[]) {
int sockfd, n;
struct sockaddr_in serv_addr;
struct hostent * server;
char buffer[256];
if (argc < 2) {
fprintf(stderr, "usage %s hostname\n", argv[0]);
exit(0);
}
server = gethostbyname(argv[1]);
if (server == NULL) {
fprintf(stderr, "ERROR, no such host\n");
exit(0);
}
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
printf("ERROR opening socket\n");
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(PORT);
serv_addr.sin_addr = * ((struct in_addr * ) server -> h_addr);
bzero( & (serv_addr.sin_zero), 8);
if (connect(sockfd, (struct sockaddr * ) & serv_addr, sizeof(serv_addr)) < 0)
printf("ERROR connecting\n");
printf("Enter the message: ");
bzero(buffer, 256);
fgets(buffer, 256, stdin);
/* write in the socket */
n = write(sockfd, buffer, strlen(buffer));
if (n < 0)
printf("ERROR writing to socket\n");
bzero(buffer, 256);
printf("%s\n", buffer);
close(sockfd);
return 0;
}
The line:
if (newSockfd = accept(serverSockfd, (struct sockaddr *)&cli_addr, &clilen) < 0)
will set newSockfd to 0 if accept() succeeds, rather than to the descriptor of the socket. This is because < has a higher precedence than =, so the compiler behaves as-if you had written this:
if (newSockfd = (accept(serverSockfd, (struct sockaddr *)&cli_addr, &clilen) < 0))
You need to write this instead:
if ((newSockfd = accept(serverSockfd, (struct sockaddr *)&cli_addr, &clilen)) < 0)

C Socket Programming Server to Client using User Input

I am trying to modify some client and server c code so that it takes a user input on the client, send it to the server and the server sends back the corresponding value. I am not very familiar with c programming; therefore, my error is most likely syntax related.
Server Code:
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <time.h>
int main(int argc, char *argv[])
{
int listenfd, connfd;
struct sockaddr_in serv_addr;
char sendBuff[1025];
char from_client[1025];
time_t ticks;
listenfd = socket(AF_INET, SOCK_STREAM, 0);
memset(&serv_addr, '0', sizeof(serv_addr));
memset(sendBuff, '0', sizeof(sendBuff));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(5000);
bind(listenfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
listen(listenfd, 10);
while(1)
{
connfd = accept(listenfd, (struct sockaddr*)NULL, NULL);
recv(connfd, from_client, sizeof(from_client), 0);
printf("%s", "Letter Recieved\n");
if(from_client == 't')
{
ticks = time(NULL);
snprintf(sendBuff, sizeof(sendBuff), "%.24s\r\n", ctime(&ticks));
write(connfd, sendBuff, strlen(sendBuff));
}
if(from_client == 'n')
{
sendBuff == "Marcus Baker";
send(connfd, sendBuff, sizeof(sendBuff), 0);
}
if(from_client == 'i')
{
sendBuff == "201604543";
send(connfd, sendBuff, sizeof(sendBuff), 0);
}
if(from_client == 'q')
{
return 0;
}
close(connfd);
sleep(1);
}
}
Client Code:
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <arpa/inet.h>
int main(int argc, char *argv[])
{
int sockfd, n = 0;
char letter[1024];
printf("Enter a Character (t, n, i, q): ");
scanf("%c",&letter);
char recvBuff[1024];
struct sockaddr_in serv_addr;
if(argc != 2)
{
printf("\n Usage: %s <ip of server> \n",argv[0]);
return 1;
}
memset(recvBuff, '0',sizeof(recvBuff));
if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
printf("\n Error : Could not create socket \n");
return 1;
}
memset(&serv_addr, '0', sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(5000);
if(inet_pton(AF_INET, argv[1], &serv_addr.sin_addr)<=0)
{
printf("\n inet_pton error occured\n");
return 1;
}
if( connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
{
printf("\n Error : Connect Failed \n");
return 1;
}
while ( (n = read(sockfd, recvBuff, sizeof(recvBuff)-1)) > 0)
{
recvBuff[n] = 0;
if(fputs(recvBuff, stdout) == EOF)
{
printf("\n Error : Fputs error\n");
}
}
if(n < 0)
{
printf("\n Read error \n");
}
int toServer = send(sockfd, letter, sizeof(letter), 0);
printf("%s", "Letter Sent\n");
recv(sockfd, recvBuff, sizeof(recvBuff), 0);
printf("%c", recvBuff);
return 0;
}
Any information would be greatly appreciated.
I have tried several different iteration following different stack overflow guides but none seem to work. When I try to compile both pieces of code, I get warnings about the user input potion of the code, something about scanf expects a char*.
I suggest you use a known good client, netcat or socat, then fix the server side first:
server: You need to deference from_client to compare against the first letter:
if(*from_client == 't') {
and the server returns the right ting:
$ socat - tcp-connect:localhost:5000
t
Wed Feb 1 00:04:36 2023
server: sendBuff == "Marcus Baker" is a comparison and always false, and you just send send as many bytes as needed instead of the whole buffer:
strcpy(sendBuff, "Marcus Baker");
send(connfd, sendBuff, strlen(sendBuff), 0);
and testing it:
n
Marcus Baker
server: sendBuff == "201604543" is a comparison. You have to decide if you want to send it as a string or binary, and if binary if you want a particular encoding (little or big indian). Using a binary and assume the same encoding on both client and server:
memcpy(sendBuff, &(int) { 201604543 }, sizeof(int));
send(connfd, sendBuff, sizeof(int), 0);
and the result is (note the use of od -t d4 to decode the integer value):
socat - tcp-connect:localhost:5000 | od -t d4
i
0000000 201604543
0000004
Now we know the server works (better) so let's start working on the client.
client: After the client connects it does a read() but server is doing a recv(). Client is expected to write to server so let's just remove this block:
while ( (n = read(sockfd, recvBuff, sizeof(recvBuff)-1)) > 0) {
recvBuff[n] = 0;
if(fputs(recvBuff, stdout) == EOF)
{
printf("\n Error : Fputs error\n");
}
}
if(n < 0) {
printf("\n Read error \n");
}
server: Now when we send 't' the server responds with time but with a bunch of 0. Going back to server we see it sends the whole buffer so let's fix that:
int n = snprintf(sendBuff, sizeof(sendBuff), "%.24s\r\n", ctime(&ticks));
write(connfd, sendBuff, n);
client: We still get a bunch of 0 after the time so let's record how much data we get from server and only print that out:
printf("%s", "Letter Sent\n");
ssize_t recvLen = recv(sockfd, recvBuff, sizeof(recvBuff), 0);
printf("%.*s", (int) recvLen, recvBuff);
and now the client reports:
Enter a Character (t, n, i, q): t
Letter Sent
Wed Feb 1 00:26:13 2023
client: The data we get for 'i' looks weird:
Enter a Character (t, n, i, q): i
Letter Sent
=
This is because it's binary data so we need to decode it:
if(*letter = 'i') {
printf("%d", *(int *) recvBuff);
} else {
// ...
and the output is now as expected:
Enter a Character (t, n, i, q): i
Letter Sent
201604543
client: 'q' prints doesn't look right:
Letter Sent
808464432
That's because we don't actually expect to get any more data:
printf("%s", "Letter Sent\n");
if(*letter == 'q')
return 0;
server: When client sends a 'q' we return but this leaves the socket in a timeout state. It's better to close it first:
if(*from_client == 'q') {
close(connfd);
return 0;
}
Here is the programs as changed:
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <arpa/inet.h>
int main(int argc, char *argv[]) {
int sockfd, n = 0;
char letter[1024];
printf("Enter a Character (t, n, i, q): ");
scanf("%c",&letter);
char recvBuff[1024];
struct sockaddr_in serv_addr;
if(argc != 2) {
printf("\n Usage: %s <ip of server> \n",argv[0]);
return 1;
}
memset(recvBuff, '0',sizeof(recvBuff));
if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
printf("\n Error : Could not create socket \n");
return 1;
}
memset(&serv_addr, '0', sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(5000);
if(inet_pton(AF_INET, argv[1], &serv_addr.sin_addr)<=0) {
printf("\n inet_pton error occured\n");
return 1;
}
if( connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
printf("\n Error : Connect Failed \n");
return 1;
}
int toServer = send(sockfd, letter, sizeof(letter), 0);
printf("%s", "Letter Sent\n");
if(*letter == 'q')
return 0;
ssize_t recvLen = recv(sockfd, recvBuff, sizeof(recvBuff), 0);
if(*letter = 'i') {
printf("%d", *(int *) recvBuff);
} else {
printf("%.*s", (int) recvLen, recvBuff);
}
}
server.c:
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <time.h>
int main(int argc, char *argv[]) {
int listenfd, connfd;
struct sockaddr_in serv_addr;
char sendBuff[1025];
char from_client[1025];
time_t ticks;
listenfd = socket(AF_INET, SOCK_STREAM, 0);
memset(&serv_addr, '0', sizeof(serv_addr));
memset(sendBuff, '0', sizeof(sendBuff));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(5000);
bind(listenfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
listen(listenfd, 10);
for(;;) {
connfd = accept(listenfd, NULL, NULL);
recv(connfd, from_client, sizeof(from_client), 0);
printf("%s", "Letter Recieved\n");
if(*from_client == 't') {
ticks = time(NULL);
int n = snprintf(sendBuff, sizeof(sendBuff), "%.24s\r\n", ctime(&ticks));
write(connfd, sendBuff, n);
}
if(*from_client == 'n') {
strcpy(sendBuff, "Marcus Baker");
send(connfd, sendBuff, strlen(sendBuff), 0);
}
if(*from_client == 'i') {
memcpy(sendBuff, &(int) { 201604543 }, sizeof(int));
send(connfd, sendBuff, sizeof(int), 0);
}
if(*from_client == 'q') {
return 0;
}
close(connfd);
sleep(1);
}
}
(not fixed) I suggest you extract the shared port number and store in a header file that you can include in both client and server. For example:
#define SERVER_PORT 5000
Then use that constant instead of hard-coding the magic value 5000.
(not fixed) Audit all calls to ensure you check the return value and handle errors. Failing to do so will waste time.

modify c socket program to send file from server to client

Modify the following socket program and let the server send a file to the client.
I'm stuck with this i can't figure this out.
below is the server and client that where given to me. right now the server will send the client the time stamp.
Socket Server Example (server.c)
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <time.h>
int main(int argc, char *argv[])
{
int listenfd = 0, connfd = 0;
struct sockaddr_in serv_addr;
char sendBuff[1025];
time_t ticks;
listenfd = socket(AF_INET, SOCK_STREAM, 0);
memset(&serv_addr, '0', sizeof(serv_addr));
memset(sendBuff, '0', sizeof(sendBuff));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(5000);
bind(listenfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
listen(listenfd, 10);
while(1)
{
connfd = accept(listenfd, (struct sockaddr*)NULL, NULL);
ticks = time(NULL);
snprintf(sendBuff, sizeof(sendBuff), "%.24s\r\n",
ctime(&ticks));
write(connfd, sendBuff, strlen(sendBuff));
close(connfd);
sleep(1);
}
}
Socket Client Example (client.c)
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <arpa/inet.h>
int main(int argc, char *argv[])
{
int sockfd = 0, n = 0;
char recvBuff[1024];
struct sockaddr_in serv_addr;
if(argc != 2)
{
printf("\n Usage: %s <ip of server> \n",argv[0]);
return 1;
}
memset(recvBuff, '0',sizeof(recvBuff));
if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
printf("\n Error : Could not create socket \n");
return 1;
}
memset(&serv_addr, '0', sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(5000);
if(inet_pton(AF_INET, argv[1], &serv_addr.sin_addr)<=0)
{
printf("\n inet_pton error occured\n");
return 1;
}
if( connect(sockfd, (struct sockaddr *)&serv_addr,
sizeof(serv_addr)) < 0)
{
printf("\n Error : Connect Failed \n");
return 1;
}
while ( (n = read(sockfd, recvBuff, sizeof(recvBuff)-1)) > 0)
{
recvBuff[n] = 0;
if(fputs(recvBuff, stdout) == EOF)
{
printf("\n Error : Fputs error\n");
}
}
if(n < 0)
{
printf("\n Read error \n");
}
return 0;
}
If you don't want to or can't read the whole content of the file you wish to send at once into memory, use a loop with your buffer:
#include <fcntl.h>
if (argv[1]) // or whereever you get the file name from
{
int fd = open(argv[1], O_RDONLY);
if (fd < 0) perror(argv[1]);
else
{
ssize_t n;
while (n = read(fd, sendBuff, sizeof sendBuff), n > 0)
if (send(connfd, sendBuff, n, MSG_NOSIGNAL) < 0)
{ perror("send"); break; }
close(fd);
if (n < 0) perror("read");
}
}
In the client use a similar loop. Be aware that the file might contain NUL characters, so functions like fputs, operating on C strings, are inept.
while ((n = read(sockfd, recvBuff, sizeof recvBuff)) > 0)
if (write(1, recvBuff, n) < 0) perror("write");
Read the content of the file you wish to send, and save it into a string:
char *loadFileContent(char *fileName, size_t *len){
FILE* input_file = fopen(fileName, "rb");
size_t stat;
if(!input_file){
OCSP_ERR_INDEX = OCSP_LOG_ERR_load_file_fail;
return NULL;
}
fseek(input_file, 0, SEEK_END);
long int input_file_size = ftell(input_file);
rewind(input_file);
char *file_contents = malloc((input_file_size + 1) * (sizeof(char)));
stat = fread(file_contents, sizeof(char), (size_t) input_file_size, input_file);
if(stat<1){
OCSP_ERR_INDEX = OCSP_LOG_ERR_load_file_fail;
return NULL;
}
fclose(input_file);
file_contents[input_file_size] = 0;
*len = (size_t) input_file_size;
return file_contents;
}
In your code, modify the line in server that is supposed to send response to client.
So this line write(connfd, sendBuff, strlen(sendBuff)); becomes:
size_t len;
char *text = loadFileContent("myfile.txt", &len);
write(connfd, text, len);

synchronization in simple socket programming in C

I want to create a simple multithreaded chat application in C using api. For the beginning, i wrote a simple server communicating with client but there is a problem in the order messages sent.
example output:
in server
*new_sock socket number: 4
Server:hello client
Client:hello server
Server:how are you?
Client:
Server:
in client
Server:hello client
Client:hello server
Server:how are you?
Client:
//server code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <pthread.h>
void* connection_handler(void* socket_descriptor)
{
int socket = *(int *)socket_descriptor;
int n;
char server_buffer[256];
memset(server_buffer, 0, sizeof(server_buffer));
printf("Server:");
gets(server_buffer);
send(socket, server_buffer, strlen(server_buffer), 0);
memset(server_buffer, 0, sizeof(server_buffer));
while ((n = recv(socket, server_buffer, 255, 0)) > 0)
{
server_buffer[n] = '\0';
printf("Client:%s\n", server_buffer);
memset(server_buffer, 0, sizeof(server_buffer));
printf("Server:");
gets(server_buffer);
send(socket, server_buffer, strlen(server_buffer), 0);
memset(server_buffer, 0, sizeof(server_buffer));
n = 0;
}
close(socket);
free(socket_descriptor);
return 0;
}
int main(int argc, char *argv[])
{
int server_sock, client_sock, portno, client_len, n;
int *new_sock;
struct sockaddr_in server_addr, client_addr;
if(argc < 2)
{
printf("ERROR: no port provided.\n");
exit(1);
}
server_sock = socket(AF_INET, SOCK_STREAM, 0);
if(server_sock < 0)
{
printf("ERROR: opening socket.");
exit(1);
}
portno = atoi(argv[1]);
memset((char *)&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(portno);
server_addr.sin_addr.s_addr = INADDR_ANY;
if( bind(server_sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0 )
{
printf("ERROR: binding socket.");
exit(1);
}
listen(server_sock, 5);
pthread_t handler_thread;
while( client_sock = accept(server_sock, (struct sockaddr *)&client_addr, &client_len) )
{
new_sock = malloc(sizeof(int));
*new_sock = client_sock;
printf("*new_sock socket number: %d\n", *new_sock);
if( pthread_create(&handler_thread, (void *)NULL, connection_handler, (void *)new_sock) < 0)
{
printf("ERROR: creating thread\n");
exit(1);
}
}
pthread_join(handler_thread, NULL);
printf("server shut down.\n");
return 0;
}
//client code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
int main(int argc, char* argv[])
{
int sock_descriptor, portno, n;
struct sockaddr_in server_addr;
char buffer[256];
if (argc != 2)
{
printf("usage: %s port\n", argv[0]);
exit(1);
}
portno = atoi(argv[1]);
sock_descriptor = socket(AF_INET, SOCK_STREAM, 0);
if (sock_descriptor < 0)
{
printf("ERROR: creating socket!\n");
exit(1);
}
memset((char *)&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = INADDR_ANY;
server_addr.sin_port = htons(portno);
if (connect(sock_descriptor, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0)
{
printf("ERROR: connecting server!\n");
exit(1);
}
memset(buffer, 0, sizeof(buffer));
while((n = recv(sock_descriptor, buffer, 255, 0)) > 0)
{
buffer[n] = '\0';
printf("Server:%s\n", buffer);
memset(buffer, 0, sizeof(buffer));
printf("Client:");
gets(buffer);
send(sock_descriptor, buffer, sizeof(buffer), 0);
memset(buffer, 0, sizeof(buffer));
}
if (n <= 0)
{
printf("ERROR: reading from socket");
exit(1);
}
return 0;
}
Join the threads right after it has been created , accept is a blocking call (I assume you have not modified the default behavior) . Threads are complex to analyze however , the call to join wont even come since blocking accept call in while loop.
while(1)
{
//do something here
...
if( pthread_create(&handler_thread, (void *)NULL, connection_handler, (void *)new_sock) < 0)
{
printf("ERROR: creating thread\n");
exit(1);
}
pthread_join(handler_thread, NULL); //Use it right after creating thread
}

Socket programming in C with user define ISN

I am doing a simple TCP socket programming as a test. I ported over the code from the following article:
C Socket Programming for Linux with a Server and Client Example Code
However, there are a little change I need to make, which is to set the initial sequence number (ISN) to a user-defined value on both client and server side.
Client:
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <arpa/inet.h>
int main(int argc, char *argv[])
{
int sockfd = 0, n = 0;
char recvBuff[1024];
struct sockaddr_in serv_addr;
if(argc != 2)
{
printf("\n Usage: %s <ip of server> \n",argv[0]);
return 1;
}
memset(recvBuff, '0',sizeof(recvBuff));
if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
printf("\n Error : Could not create socket \n");
return 1;
}
memset(&serv_addr, '0', sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(5000);
if(inet_pton(AF_INET, argv[1], &serv_addr.sin_addr)<=0)
{
printf("\n inet_pton error occured\n");
return 1;
}
if( connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
{
printf("\n Error : Connect Failed \n");
return 1;
}
while ( (n = read(sockfd, recvBuff, sizeof(recvBuff)-1)) > 0)
{
recvBuff[n] = 0;
if(fputs(recvBuff, stdout) == EOF)
{
printf("\n Error : Fputs error\n");
}
}
if(n < 0)
{
printf("\n Read error \n");
}
return 0;
}
Server:
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <time.h>
int main(int argc, char *argv[])
{
int listenfd = 0, connfd = 0;
struct sockaddr_in serv_addr;
char sendBuff[1025];
time_t ticks;
listenfd = socket(AF_INET, SOCK_STREAM, 0);
memset(&serv_addr, '0', sizeof(serv_addr));
memset(sendBuff, '0', sizeof(sendBuff));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(5000);
bind(listenfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
listen(listenfd, 10);
while(1)
{
connfd = accept(listenfd, (struct sockaddr*)NULL, NULL);
ticks = time(NULL);
snprintf(sendBuff, sizeof(sendBuff), "%.24s\r\n", ctime(&ticks));
write(connfd, sendBuff, strlen(sendBuff));
close(connfd);
sleep(1);
}
}
Can someone enlighten me on which part of the code I should modify?

Resources