How to use strtok to parse string from TCP server - c

I am using the following program to listen to server and the use "\r" delimiter.
When I run the following program, it doesn't output anything.
How can I parse string by removing delimiter in socket communication?
#include <arpa/inet.h> // inet_addr()
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h> // bzero()
#include <sys/socket.h>
#include <unistd.h> // read(), write(), close()
#define MAX 80
#define PORT 8080
#define SA struct sockaddr
void func(int sockfd)
{
char buff[MAX];
int n;
char str[MAX];
for (;;) {
bzero(buff, sizeof(buff));
printf("Enter the string : ");
n = 0;
while ((buff[n++] = getchar()) != '\n')
;
write(sockfd, buff, sizeof(buff));
bzero(buff, sizeof(buff));
read(sockfd, buff, sizeof(buff));
strcpy(str,buff);
char delim[]="\r";
char *str = strtok(str,delim);
while(str != NULL)
{
printf("from my prog = %s \n",str);
str = strtok(NULL,delim);
}
if ((strncmp(buff, "exit", 4)) == 0) {
printf("Client Exit...\n");
break;
}
}
}

Related

Download a file from server using TCP

I'm trying to write a C program for a client which can download a file from the server using TCP. The client will print and save the file content after it receives the file from the server. To compile the client program it needs IP address and port number of the server. I implemented it in Linux but it displayed 0s after the received texts. The saved text file was the same. I have no idea how to output the text only. Maybe there are wrongs in the receive buffer?
Code for server:
#include <stdio.h>
#include <netdb.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <pthread.h>
#define portnum 12345
#define FILE_SIZE 500
#define BUFFER_SIZE 1024
void *client_fun(void * fd);
int main()
{
int new_fd;
pthread_t thread_id;
int server_fd=socket(AF_INET,SOCK_STREAM,0);
if(-1==server_fd)
{
perror("socket");
exit(1);
}
struct sockaddr_in server_addr;
server_addr.sin_family=AF_INET;
server_addr.sin_port=htons(portnum);
(server_addr.sin_addr).s_addr=htonl(INADDR_ANY);
if(-1==bind(server_fd,(struct sockaddr *)&server_addr,sizeof(server_addr)))
{
perror("bind");
close(server_fd);
exit(6);
}
if(-1==listen(server_fd,5))
{
perror("listen");
close(server_fd);
exit(7);
}
while(1)
{
struct sockaddr_in client_addr;
int size=sizeof(client_addr);
new_fd=accept(server_fd,(struct sockaddr *)&client_addr,&size);
if(new_fd < 0)
{
perror("accept");
continue;
}
printf("accept client ip锛?s:%d\n",inet_ntoa(client_addr.sin_addr),client_addr.sin_port);
//printf("new_fd=%d\n",new_fd);
if (new_fd > 0)
{
pthread_create(&thread_id, NULL, client_fun, (void *)&new_fd);
pthread_detach(thread_id);
}
}
close(server_fd);
return 0;
}
void *client_fun(void *arg)
{
int new_fd = *((int *)arg);
int file2_fp;
int len;
char buffer[BUFFER_SIZE];
memset( buffer,0, sizeof(buffer) );
while(1)
{
if((len=recv(new_fd, buffer, sizeof(buffer), 0)) <= 0)
{
continue;
}
char file_name[FILE_SIZE];
memset( file_name,0, sizeof(file_name) );
strncpy(file_name, buffer, strlen(buffer)>FILE_SIZE?FILE_SIZE:strlen(buffer));
memset( buffer,0, sizeof(buffer) );
printf("Client requests file %s\n", file_name);
if( strcmp(file_name,"exit")==0 )
{
break;
}
file2_fp = open(file_name,O_RDONLY,0777);
if(file2_fp<0)
{
printf("File %s Not Found\n", file_name);
char* err_info = "File not found\n";
if (write(new_fd, err_info, sizeof(err_info)) < 0)
{
printf("Send error information failed\n");
break;
}
continue;
}
else
{
int length = 0;
memset( buffer,0, sizeof(buffer) );
while( (length = read(file2_fp, buffer, sizeof(buffer))) > 0 )
{
if( write(new_fd, buffer, length) < 0)
{
printf("Send File %s Failed.\n", file_name);
break;
}
memset( buffer,0, sizeof(buffer) );
}
close(file2_fp);
printf("Transfer file %s successfully!\n", file_name);
}
}
close(new_fd);
}
Code for client:
#include <stdio.h>
#include <netdb.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <pthread.h>
int main(int argc, char *argv[])
{
int sockfd = 0;
char recvBuff[1024];
char file_name[500];
char *serverIP=argv[1];
int portno=atoi(argv[2]);
printf("IP Addresses: %s Port Number: %s\n", argv[1], argv[2]);
memset(recvBuff,'0',sizeof(recvBuff));
struct sockaddr_in server_addr;
/* Creat a socket*/
sockfd = socket(AF_INET, SOCK_STREAM, 0);
/*Initialize sockaddr_in structure*/
server_addr.sin_family=AF_INET;
server_addr.sin_port=htons(portno);
(server_addr.sin_addr).s_addr=inet_addr(serverIP);
/*Attempt a connection*/
printf("Connect status: ");
if (connect(sockfd,(struct sockaddr *)&server_addr,sizeof(server_addr))<0)
{
printf("fail\n");
return 0;
}
printf("success\n");
/*Request file from server*/
while(1)
{
printf("Input the file name to be requested from the server: ");
fgets(file_name,500, stdin);
char *p=strchr(file_name,'\n');
if (p) *p=0;
if (send(sockfd, file_name, strlen(file_name), 0)<0)
{
printf("Send failed.\n");
break;
}
printf("Send success.\n");
if (strcmp(file_name,"exit")==0)
break;
int length=0;
printf("Send status: ");
if (length=read(sockfd, recvBuff, sizeof(recvBuff))<0)
{
printf("fail\n");
continue;
}
else if (strcmp(recvBuff,"File not found\n")==0)
{
printf("fail\n");
continue;
}
else
{
printf("success\n");
/*Create file where text will be stored*/
FILE *fp;
fp=fopen("received_file.txt","w");
printf("Open file status: ");
if (fp==NULL)
{
printf("fail\n");
continue;
}
printf("success\n");
printf("Received text: ");
if (fprintf(fp, "%s", recvBuff)<0)
{
printf("Save status: fail\n");
continue;
}
fflush(fp);
printf("%s",recvBuff);
memset(recvBuff,0,1024);
while ((length=read(sockfd, recvBuff, sizeof(recvBuff)))>0)
{
if (fprintf(fp, "%s", recvBuff)<0)
{
printf("Save status: fail\n");
break;
}
fflush(fp);
printf("%s",recvBuff);
memset(recvBuff,0,1024);
}
printf("Save status: success");
}
}
}
Another question is that the client is supposed to keep asking for files until it sends an 'exit'. But it stopped asking the client to input the file name after the first file was received. What's wrong with the loop?
you have several issues.
first: - comparison operator has precedence over assignment so length gets FALSE(0) value instead of the real number of received data
if (length=read(sockfd, recvBuff, sizeof(recvBuff))<0)
it should be:
if ((length=read(sockfd, recvBuff, sizeof(recvBuff)))<0)
second: you are operating with zero terminated strings but you do not send zero ('\0') from server and client does not set it at the end of the data block.
So you need to set it explicitly at client side here
if ((length=read(sockfd, recvBuff, sizeof(recvBuff)))<0)
{
printf("fail\n");
continue;
}
else if (strcmp(recvBuff,"File not found\n")==0)
{
printf("fail\n");
continue;
}
else
{
recvBuff[length]='\0';
and here:
while ((length=read(sockfd, recvBuff, sizeof(recvBuff)))>0){
recvBuff[length]='\0';

Encapsulation and auxiliary functions for using UDP sockets on a client and server

I am using the UDP auxiliary functions encapsulated below replacing the calls the functions of the sockets libraries to simulate and allow some testing on the UDP client and server. But I am not able to make the connection between them and pass the arguments correctly.
/********auxiliary functions for using UDP sockets*********/
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <strings.h>
#include "tp_socket.h"
#define MTU 1024
int tp_mtu(void)
{
fprintf(stderr,"tp_mtu called\n");
return MTU;
}
int tp_sendto(int so, char* buff, int buff_len, so_addr* to_addr)
{
int count;
fprintf(stderr,"tp_sendto called (%d bytes)\n", buff_len);
count = sendto(so, (void*)buff, buff_len, 0,
(struct sockaddr*) to_addr, sizeof(struct sockaddr_in));
fprintf(stderr,"tp_sendto returning (sent %d bytes)\n", count);
return count;
}
int tp_recvfrom(int so, char* buff, int buff_len, so_addr* from_addr)
{
int count;
unsigned int sockaddr_len = sizeof(struct sockaddr_in);
fprintf(stderr,"tp_recvfrom called (%d bytes)\n",buff_len);
count = recvfrom(so,(void*)buff,(size_t)buff_len,0,
(struct sockaddr*) from_addr, &sockaddr_len);
fprintf(stderr,"tp_recvfrom returning (received %d bytes)\n",count);
return count;
}
int tp_init(void)
{
fprintf(stderr,"tp_init called\n");
return 0;
}
int tp_socket(unsigned short port)
{
int so;
struct sockaddr_in local_addr;
int addr_len =sizeof(local_addr);
fprintf(stderr,"tp_socket called\n");
if ((so=socket(PF_INET,SOCK_DGRAM,0))<0) {
return -1;
}
if (tp_build_addr(&local_addr,INADDR_ANY,port)<0) {
return -2;
}
if (bind(so, (struct sockaddr*)&local_addr, sizeof(local_addr))<0) {
return -3;
}
return so;
}
int tp_build_addr(so_addr* addr, char* hostname, int port)
{
struct hostent* he;
fprintf(stderr,"tp_build_addr called\n");
addr->sin_family = PF_INET;
addr->sin_port = htons(port);
if (hostname==NULL) {
addr->sin_addr.s_addr = INADDR_ANY;
} else {
if ((he=gethostbyname(hostname))==NULL) {
return -1;
}
bcopy(he->h_addr,&(addr->sin_addr.s_addr),sizeof(in_addr_t));
}
return 0;
}
My code at the moment of the UDP client:
/********clientUDP*********/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include "tp_socket.h"
int main(int argc, char *argv[])
{
so_addr to_addr;
char *ip_server;
char my_buffer[10];
int port_servidor, tam_buffer;
if (argc != 5)
{
perror("Error");
exit(-1);
}
*ip_server = argv[1];
port_server = atoi(argv[2]);
char arquivo = argv[3];
tam_buffer = atoi(argv[4]);
tp_init();
tp_socket(port);
tp_build_addr(&to_addr, ip_server, port_server);
exit(0);
}
My code at the moment of the UDP server:
/********serverUDP*********/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include "tp_socket.h"
int main(int argc, char *argv[])
{
so_addr my_addr;
int aux, so, mtu, port_server,tam_buffer,n;
char *archive;
char buffer[10];
FILE *file;
if (argc != 3)
{
perror("Error");
exit(-1);
}
port_server = atoi(argv[1]);
tam_buffer = atoi(argv[2]);
aux = tp_init();
if (aux < 0)
{
perror("error");
exit(aux);
}
mtu = tp_mtu();
so = tp_socket(port_server);
tp_recvfrom(so, buffer, 10 , &my_addr);
n = read( so,tam_buffer,1);
file = fopen(archive,"r");
if ( file != NULL )
{
n=fread(buffer,1,atoi(argv[2]),file);
while ( n > 0)
{
write(so,buffer,n);
n=fread(buffer,1, atoi(argv[2]),file);
}
} else
{
printf("error\n");
exit(0);
}
fclose(file);
shutdown(so,2);
close();
return 0;
}
Could someone please explain how I use the auxiliary functions to connect the client to the server and transfer files? I've be I've been locked up a long time at this stage.

Error in server programming

I'm trying to write a simple code for a server to print something from a function
This code gives me an error :
request for member ‘sin_addr’ in something not a structure or union
and I don't understand why
can you help me?
#include <sys/types.h>
#include <netinet/in.h>
#include <inttypes.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <strings.h>
#include <unistd.h>
#include <stdio.h>
void printsin(struct sockaddr_in *s, char *str1, char *str2) {
printf("%s\n", str1);
printf("%s: ", str2);
printf("%d = ,", s.sin_addr.s_addr);
printf(" %d = ", s.sin_port);
printf("\n");
}
int main(int argc, char *argv[])
{
int socket_fd, cc, fsize;
struct sockaddr_in s_in, from;
struct { char head; u_long body; char tail;} msg;
socket_fd = socket (AF_INET, SOCK_DGRAM, 0);
bzero((char *) &s_in, sizeof(s_in)); /* They say you must do this */
s_in.sin_family = (short)AF_INET;
s_in.sin_addr.s_addr = htonl(INADDR_ANY); /* WILDCARD */
s_in.sin_port = htons((u_short)0x3333);
printsin( &s_in, "RECV_UDP", "Local socket is:");
fflush(stdout);
bind(socket_fd, (struct sockaddr *)&s_in, sizeof(s_in));
for(;;) {
fsize = sizeof(from);
cc = recvfrom(socket_fd,&msg,sizeof(msg),0,(struct sockaddr *)&from,&fsize);
//printsin( &from, "recv_udp: ", "Packet from:");
printf("Got data ::%c%ld%c\n",msg.head,(long) ntohl(msg.body),msg.tail);
fflush(stdout);
}
return 0;
}
Thank you
printf("%d = ,", s->sin_addr.s_addr);
printf(" %d = ", s->sin_port);
That should fix it you pass it in as a pointer then you never deference it.

Socket programming in C using http post

Want to do client-server programming using c in windows7, it should send string to server using http POST method. The paramater in POST method should include the ip-address etc:
I got this code from http://souptonuts.sourceforge.net/code/http_post.c.html and changed it for running it on windows, but still 1 error is coming:
#ifdef WIN32
#include <winsock2.h>
#include <ws2tcpip.h>
#include <windows.h>
#else
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/wait.h>
#include <netdb.h>
#include <assert.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <signal.h>
#include <ctype.h>
#define SA struct sockaddr
#define MAXLINE 4096
#define MAXSUB 200
#define LISTENQ 1024
extern int h_errno;
ssize_t process_http(int sockfd, char *host, char *page, char *poststr)
{
char sendline[MAXLINE + 1], recvline[MAXLINE + 1];
ssize_t n;
snprintf(sendline, MAXSUB,
"POST %s HTTP/1.0\r\n"
"Host: %s\r\n"
"Content-type: application/x-www-form-urlencoded\r\n"
"Content-length: %d\r\n\r\n"
"%s", page, host, strlen(poststr), poststr);
write(sockfd, sendline, strlen(sendline));
while ((n = read(sockfd, recvline, MAXLINE)) > 0) {
recvline[n] = '\0';
printf("%s", recvline);
}
return n;
}
int main(void)
{
int sockfd;
struct sockaddr_in servaddr;
char **pptr;
//********** You can change. Puy any values here *******
char *hname = "souptonuts.sourceforge.net";
char *page = "/chirico/test.php";
char *poststr = "mode=login&user=test&password=test\r\n";
//*******************************************************
char str[50];
struct hostent *hptr;
if ((hptr = gethostbyname(hname)) == NULL) {
fprintf(stderr, " gethostbyname error for host: %s: %s",
hname, hstrerror(h_errno));
exit(1);
}
printf("hostname: %s\n", hptr->h_name);
if (hptr->h_addrtype == AF_INET
&& (pptr = hptr->h_addr_list) != NULL) {
printf("address: %s\n",
inet_ntop(hptr->h_addrtype, *pptr, str,
sizeof(str)));
} else {
fprintf(stderr, "Error call inet_ntop \n");
}
sockfd = socket(AF_INET, SOCK_STREAM, 0);
// bzero(&servaddr, sizeof(servaddr));
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(80);
inet_pton(AF_INET, str, &servaddr.sin_addr);
connect(sockfd, (SA *) & servaddr, sizeof(servaddr));
process_http(sockfd, hname, page, poststr);
close(sockfd);
exit(0);
}
The error which is coming on MinGW compiler is:
httppost.c:33:12: error: conflicting types for 'WSAGetLastError'
In file included from httppost.c:5:0:
c:\mingw\bin\../lib/gcc/mingw32/4.7.2/../../../../include/winsock2.h:594:32: n
e: previous declaration of 'WSAGetLastError' was here
The code you've got is under linux based systems, but in MinGW (Windows) unfortunately the identifier h_errno is taken before.
The problem is this line
extern int h_errno;
it's defined previously in windows header files, then you can not use it:
#define h_errno WSAGetLastError()
Just use another identifier instead of h_errno, or even just remove that line!
Maybe you should try the wininet library.
http://msdn.microsoft.com/en-us/library/windows/desktop/aa383630(v=vs.85).aspx

Connect Error in Basic TCP Client Server Programming in C

The server has to echo the message sent by the client using C program in Linux.I'm using Ubuntu OS (I don't know whether this information is useful or not!). It worked for the first time. But for the second time, it gave 'Error Connection'. I tried changing port numbers. But still it didn't work. Kindly guide me. I'm a beginner.
server.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <netinet/in.h>
int main()
{
int sd, sd1, len, confd, n;
struct sockaddr_in ser, cli;
char msg[50];
if((sd = socket(AF_INET,SOCK_STREAM, 0)) < 0)
printf("\nSocket creation error\n");
bzero(&ser, sizeof(ser));
ser.sin_family = cli.sin_family = PF_INET;
ser.sin_port = htons(10000);
ser.sin_addr.s_addr = htonl(INADDR_ANY);
len = sizeof(ser);
if ((bind(sd, (struct sockaddr*)&ser, len)) < 0) {
printf("\nBind Error");
exit(0);
}
if (listen(sd, 2) == 0) {
if ((sd1 = accept(sd, (struct sockaddr*)&ser, &len)) > 0) {
do {
bzero(&msg, 50);
read(sd1, msg, 50);
//int m=(int)msg;
printf("\nMessage from client:%s\n", msg);
write(sd1, msg, strlen(msg));
if(strcmp(msg, "exit") == 0)
break;
} while(strcmp(msg, "exit") != 0);
}
}
}
*strong text*client.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <netinet/in.h>
int main()
{
int sd, n, len;
struct sockaddr_in ser, cli;
char text[50];
if ((sd = socket(AF_INET,SOCK_STREAM, 0)) < 0)
printf("\nSocket creation error\n");
bzero(&ser, sizeof(ser));
ser.sin_family = cli.sin_family = PF_INET;
ser.sin_port = htons(10000);
ser.sin_addr.s_addr = htonl(INADDR_ANY);
len = sizeof(ser);
if ((connect(sd, (struct sockaddr*)&ser, len)) < 0) {
printf("\nError connection");
exit(0);
}
while(1) {
strcpy(text, " ");
printf("\nEnter data which is to be sent:");
scanf("%s", text);
write(sd, text, strlen(text));
read(sd, text, 50);
printf("\nEcho msg from server:%s", text);
if (strcmp(text, "exit") == 0)
break;
}
close(sd);
}
Can your client really connect to any address?
ser.sin_addr.s_addr=htonl(INADDR_ANY);
Most likely you meant to connect to a specific server:
ser.sin_addr.s_addr=inet_addr("127.0.0.1");

Resources