I am a newbie to c socket programming and c itself. I have written a small piece of code that reads raw input from another internet socket and post the data to a webserver. the received data is always numeric. however the problem seems that the http post request happens only once instead of running in a loop and the program terminates.
following is the code example
#include <sys/types.h>
#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 <netdb.h>
//define server parameters
#define WEBIP "172.16.100.2"
int main()
{
//declare variables
struct sockaddr_in my_addr,client_addr,server_addr;
struct hostent *server_host;
int true=1;
int client_socket_id,server_socket_id;
int client_id;int sin_size;
int client_bytes_received;
char send_data [1024],recv_data[1024],post_data[1024];
server_host=gethostbyname(WEBIP2);
//create a socket to listen to client
if ((client_socket_id = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("Error Creating Socket");
exit(1);
}
if (setsockopt(client_socket_id,SOL_SOCKET,SO_REUSEADDR,&true,sizeof(int)) == -1) {
perror("Setsockopt");
exit(1);
}
//create socket to connect to webserver
if ((server_socket_id = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("Error Creating Webserver Socket");
exit(1);
}
my_addr.sin_family = AF_INET;
my_addr.sin_port = htons(7070);
my_addr.sin_addr.s_addr = INADDR_ANY;
//bzero(&(my_addr.sin_zero),8);
bzero(&(server_addr.sin_zero),8);
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(WEBPORT);
server_addr.sin_addr = *((struct in_addr *)server_host->h_addr);
//bind to a socket
if (bind(client_socket_id, (struct sockaddr *)&my_addr, sizeof(struct sockaddr))== -1) {
perror("Unable to bind");
exit(1);
}
//listen to socket
if (listen(client_socket_id, 5) == -1) {
perror("Error Listening to Socket");
exit(1);
}
printf("\n\r Waiting for client on port 7070");
fflush(stdout);
while(1)
{
sin_size = sizeof(struct sockaddr_in);
client_id = accept(client_socket_id, (struct sockaddr *)&client_addr,&sin_size);
printf("\n I got a connection from (%s , %d)",
inet_ntoa(client_addr.sin_addr),ntohs(client_addr.sin_port));
//connect to remote server
if (connect(server_socket_id, (struct sockaddr *)&server_addr,sizeof(struct sockaddr)) == -1)
{
perror("Error Connecting to Web Server");
exit(1);
}
while(1){
//send some data to client
send(client_id,"Hello, World!",13, 0);
//receive some data from client
client_bytes_received=recv(client_id,recv_data,1024,0);
recv_data[client_bytes_received] = '\0';
//print received_data
int c_length=strlen(recv_data)+11;
printf("\n\rRecieved data (%d bytes %d words)= %s " , client_bytes_received,c_length,recv_data);
//post dta to webserver
fflush(stdout);
bzero(&post_data,1024);
sprintf(post_data,"POST /environment.php HTTP/1.1\r\n"
"Host: 172.16.100.2\r\n"
"User-Agent: C Example Client\r\n"
"Content-Type: application/x-www-form-urlencoded\r\n"
"Content-Length: %d\r\n\r\n"
"track_data=%s",c_length,recv_data);
write(server_socket_id,post_data,strlen(post_data)+1);
bzero(&recv_data,1024);
while((client_bytes_received=read(server_socket_id,recv_data,1024))开发者_如何学C>0){
recv_data[client_bytes_received] = '\0';
if (fputs(recv_data,stdout)==EOF)
perror("web server read_error");
}
//print received_data
printf("\n\rRecieved data from webserver (%d)= %s " , client_bytes_received,recv_data);
//
bzero(&recv_data,1024);
fflush(stdout);
}
}
close(client_id);
close(client_socket_id);
return 0;
}
I have not done socket programming for years, so please bear with me. Do you need to connect, process, and then disconnect? That's the first thing that came to mind reading your code.
I am surprised this program works. You have created blocking sockets, unless you are working on a non-POSIX compliant OS. The accept call should have never returned. If accept is returning it means that your server socket is not able to go into the wait mode. Hence whatever you are seeing is most likely because of an error.
SO_NONBLOCK is the socket option you can use for creating non blocking sockets.
Since you are using the same routine for both client and server you should use select in the socket loop.
精彩评论