I'm trying make the program run multiple threads to it connects to different ports. I successfully made it work on a single thread but not multiple.
Below I have posted the code of what I'm using on XUbuntu.
server.c
#include <stdio.h>
#include <netdb.h>
#include <unistd.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
// File io storing in lof file
#include "server_portLog.h"
// Thread used to create sockets
#include "sockets_pthread.h"
#define BUFFER_SIZE 1024
int main(int argc, char *argv[]) {
// Server port number
//int portNumber = atoi(argv[1]);
// sockfd: ip-address socket, newsockfd: socket from receiving client, portNum: Which port will be listening, num_bytes: received data from client
int sockfd, newsockfd, num_bytes;
// buffer: will send & receive values from the server
char buffer[BUFFER_SIZE];
struct sockaddr_in serv_addr, cli_addr;
socklen_t clilen = sizeof(cli_addr);
// Getting all ports from command line parameters and creating a socket for each
int numPorts = argc - 1;
struct port varPorts[numPorts];
pthread_t portsSockets[numPorts];
for (int i = 0; i < numPorts; i++) {
varPorts[i].portNumber = atoi(argv[i + 1]);
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_create(&portsSockets[i], &attr, createSocket, &varPorts[i]);
}
// Infinite loop too keep listening even after connection to client closes
while (1) {
// After that all the ports entered have a socket of their own the program runs them parallel together to see if any client tries to connect with one of the ports
for (int i = 0; i <= numPorts; i++) {
pthread_join(&portsSockets[i], NULL);
/* Start listening for the clients (thread blocks) */
if (listen(varPorts[i].sockfd, 5) != 0) {
printf("Error: listen() failed for port: %d \n", varPorts[i].portNumber);
//return 3;
}
// Accepting connection from client & creating socket with that client data
newsockfd = accept(varPorts[i].sockfd, (struct sockaddr *)&cli_addr, &clilen);
if (newsockfd < 0) {
printf("Error: accept() failed for port: %d \n", varPorts[i].portNumber);
//return 4;
}
/* To send receive data */
// Clearing buffer
memset(buffer, 0, BUFFER_SIZE);
// Show data received from client
num_bytes = recv(newsockfd, buffer, BUFFER_SIZE-1, 0);
if (num_bytes < 0) {
printf("Error: recv() failed for port: %d \n", varPorts[i].portNumber);
//return 5;
}
// Checking version of server if LOGFILE it creates a file to store the ports
#if defined LOGFILE
// Checking if user wrote a fileName for the logs or going to use the default log file
if (argc == 3) {
char *textFile = argv[argc-1];
serverLogFile_Custom(buffer, textFile);
}
else {
serverLogFile_Defualt(buffer);
}
#else
// Print the port numbers that connect to server
printf("Received: Client using port- %s to connect \n", buffer);
#endif
// Closing connection with client
close(newsockfd);
}
}
return 0;
}
Sockets_pthreads.h
#include <pthread.h>
struct port {
int portNumber;
int sockfd;
};
void* createSocket(void* portNumber) {
// sockfd: ip-address socket, newsockfd: socket from receiving client, portNum: Which port will be listening, num_bytes: received data from client
int sockfd, newsockfd, num_bytes;
// buffer: will send & receive values from the server
//char buffer[BUFFER_SIZE];
struct sockaddr_in serv_addr, cli_addr;
socklen_t clilen = sizeof(cli_addr);
struct port *portStruct = (struct port*) portNumber;
// Creating a new socket with ip-Protocol_tcp
// Parameters: Internet-domain, socket-stream, TCP-protocol
sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sockfd < 0) {
printf("Error: Failed to open socket for port: %d \n", portStruct->portNumber);
//return 1;
}
// Setting all bits in padding-field to 0
memset(&serv_addr, 0, sizeof(serv_addr));
// Initializing socket in sockaddr_in (stucture)
serv_addr.sin_family = AF_INET; // Seting family-Internet
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(portStruct->portNumber); // Setting portNum (passed in command line)
// Binding the address-structure to the socket
if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
printf("Error: bind() failed for port: %d \n", portStruct->portNumber);
//return 2;
}
// Geting sockfd
portStruct->sockfd = sockfd;
pthread_exit(0);
}
Problem is not clear what needs to be implemented. If various ports sockets have to accept, then it has to happen in thread function as well as recv call. In server function there are accept and recv calls which are blocking by default.
The main function should wait for connections. Upon receiving a request from the client, you create a thread that will handle this specific connection. So you will create the threads in the loop, meaning, you can theoretically have an infinite number of threads.
However, you can add a little logic to limit the number of threads that are existing at a particular time (thread pool).
So your main loop can look like this:
while (1) {
// accept: wait for a connection request
childfd = accept(parentfd, (struct sockaddr *) &clientaddr, (socklen_t *) &clientlen);
if (childfd < 0){
fprintf(stderr,"ERROR on accept");
continue;
}
hostaddrp = inet_ntoa(clientaddr.sin_addr);
if (hostaddrp == NULL){
fprintf(stderr,"ERROR on inet_ntoa\n");
continue;
}
fprintf(stdout,"server established connection with client\n");
pthread_t new_thread;
newSock = malloc(1);
*newSock = childfd;
if( pthread_create( &new_thread , NULL , server_thread , (void*) newSock) < 0){
bzero(logMsg, MAXSTRING);
sprintf(logMsg, "Thread for connection %d could not be created",childfd);
fprintf(stderr, "%s\n", logMsg);
continue;
}
fprintf(stdout, "thread created for connection %d\n", childfd);
}
The server_thread function could look like:
void *server_thread(void* clientSock){
int childfd = *(int*)clientSock;
char buf[MAXLINE]; // message buffer
int n; // message byte size
char logMsg[MAXSTRING];
size_t siz_failresp;
// read: read input string from the client
bzero(buf, MAXLINE);
n = (int) read(childfd, buf, MAXLINE);
if (n < 0){
sprintf(logMsg, "ERROR reading from socket");
fprintf(stderr,"%s", logMsg);
close(childfd);
fprintf(stdout, "Client %d disconnected \n=================\n", childfd);
//Free the socket pointer
free(clientSock);
return NULL;
}
// else, do processing of data received...
// ...................
}
There may be unused variables here above... I just got this code from one of my projects, just removing parts that do not concern you :-)
Hope it helps
Related
So, I am working on an remote ls assignment in which we have to use TCP socket connection between two remote computers and run client.c on one side and server.c on another. Client program enters command; for e.g: ls
the server will parse it and returns the current working directory to client.
Note that I am running both programs on VM Workstation. One side is Ubuntu and another is Red Hat 6.
Issue: My client program couldn't connect to the server and its connect() function is returning -1.
I have tried to debug my program and so I am attaching the results:debug result
Note: I have hardcoded IP address and port no for the sake of debugging.
Here are the codes:
Client side:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include<netdb.h>
#include <string.h>
#include<unistd.h>
/*
Client side socket flow
socket()
|
|
v
connect()
|
|
v
recv()
*/
int main(int argc, char *argv[]) {
struct hostent *server;
struct sockaddr_in server_address;
int port_num;
int communication_status;
//create a socket
int network_socket;
//We will use 3 args while running client code.
/*
if (argc < 3) {
fprintf(stderr,"usage %s hostname port\n", argv[0]);
}*/
/*
socket(arg1,arg2,arg3)
- First arg: (AF_INET) = domain .. from IPV4 domain
- Sec arg: SOCK_STREAM - TCP Stream/Connection-Oriented
- Third arg: defines protocol - 0 for TCP <You can use RAW SOCKET HERE (SOCKETS WITH NO PROTOCOL)
*/
network_socket = socket(AF_INET,SOCK_STREAM,0);
/*
- So we can pass port no as int
- But data format is different from structure that we need to use a conversion function
- conversion function thats going to put our integer
port in right byte order is htons(agr = actual int port number we want to connect to)
*/
//define port you need to conenct remotely
port_num = 20102;
server_address.sin_port = htons(port_num);
//define server address
/*
-sin addr is field that contains structure itself
- we can use any address -- use shortcut ip.0.0.0 (INADDR_ANY)
*
/*
-now we need to use connect() to connect to other socket
- BUT FIRST WE NEED TO SPECIFY AN ADDRESS FOR SOCKET i.e. addr and port no
*/
server_address.sin_family = AF_INET;
server_address.sin_addr.s_addr = inet_addr("192.168.177.128");
//now time to connect
/*
connect()
arg1: socket
arg2: need to cast our server addfress structure to slightly different struct
from sockaddr_in to sockaddr*
arg3: sizeof the address
connect() returns integer
0 - successful connection
-1 - not successfull
*/
int connection_status;
connection_status = connect(network_socket,(struct sockaddr *) &server_address,sizeof(server_address));
//check for error with the connection
if (connection_status == -1) {
printf("There was an error making a connection to the remote socket \n\n");
}
// recieve data from the server
/*
- recv() function
- first arg: socket
- 2nd arg: address of var where data recived will end up (here it is char array)
- 3rd arg: optional flag parameter give 0
*/
//string to hold data exchanged between client and server
char buffer[256];
printf("Please enter the linux command: ");
//clears the buffer content
bzero(buffer,256);
//get linux command from the console
fgets(buffer,255,stdin);
communication_status = write(network_socket,buffer,strlen(buffer));
//check for write status
if (communication_status < 0) {
perror("Error writing to socket!");
exit(1);
}
//Now getting server response
//clear the buffer
bzero(buffer,256);
communication_status = read(network_socket,buffer,255);
if (communication_status < 0) {
perror("Error reading from socket!");
exit(1);
}
//now we have to print the server response
printf("Server>>: %s\n", buffer);
//close the socket
close(network_socket);
return 0;
}
Server side:
#include<stdio.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<netdb.h>
#include <stdlib.h>
#include <string.h>
#include<unistd.h>
int readAndParseCmdLine(char **, char **);
int main(int argc, char *argv[]) {
//Checks if the num of argument is 2, if not error message is displayed.
if(argc<2) {
fprintf(stderr,"Num of argument Error");
}
//buffer for data exchange
char buffer[256];
int clientlength, portnum, newSocket;
struct sockaddr_in server_address, cli_addr;
int communication_status,newsockfd;
//create server
int server_socket;
server_socket = socket(AF_INET, SOCK_STREAM,0);
if(server_socket == -1) {
perror("Could not connect to socket");
exit(1);
}
//define the server address
bzero((char *) &server_address, sizeof(server_address));
//Coverts the character value to integer for the portno
portnum = atoi(argv[1]);
server_address.sin_family = AF_INET;
server_address.sin_port = htons(portnum);
server_address.sin_addr.s_addr = INADDR_ANY;
//bind the socket to our specified IP and port
//bind is used exactly like we call the connection()
//OS gives resources like port number to Server through bind()
if ( bind(server_socket,(struct sockaddr*) &server_address,sizeof(server_address)) < 0 ) {
perror("Can't bind");
exit(1);
}
/*
listen()
first arg: socket
second arg: backlog (how many connection can be waiting -
essentially for this particular socket at a time - since
we are using this for one client, we can use any number)
*/
listen(server_socket,5);
clientlength = sizeof(cli_addr);
/*
define integer to hold client's socket as once we able to listen() connection
and we can actually start accepting() connections so we can read or write to
clients socket
*/
//The new socket for the client informations
/*
if(newsockfd<1)
{
sleep(1);
}
*/
newSocket = accept(server_socket,(struct sockaddr *) &cli_addr, &clientlength);
if (newSocket < 0) {
perror("ERROR on accept");
exit(1);
}
//Clears the buffer
bzero(buffer,256);
communication_status = read(newSocket,buffer,255);
if (communication_status < 0) {
perror("ERROR reading from socket");
exit(1);
}
//Buffer Stores the msg sent by the client
printf("Here is the entered bash command: %s\n",buffer);
communication_status = write(newSocket,"I got your message",18);
if (communication_status < 0)
{
error("ERROR writing to socket");
}
char *prog;
strcpy(prog, buffer);
char *args[100];
int child_pid;
//Running the Bash Commands
if(readAndParseCmdLine(&prog, args)) {
child_pid =fork();
if(child_pid == 0){ //child part
printf("\n");
execvp(prog, args); // create and run the new process and close the child process
printf("\n");
prog = NULL;
printf("Error in excuting the command- please make sure you type the right syntax.\n");
} else{ //parent part
wait(child_pid);
}
void main();
}
}
//This function reads the linux command form the buffer and parse it
//
int readAndParseCmdLine(char **prog, char **args){
int i =0;
char cmd[100]; //user command
char * temp;
temp = *prog;
if(strcmp(temp,"exit")==0){return 0;} //end program if user type exit.
char *tok;
tok = strtok(temp," \n");
while(tok != NULL){
if(i==0){
prog[0] = tok;
}
args[i] = tok;
printf("\n");
i=i+1;
tok = strtok(NULL, " \n");
}
args[i]=NULL;
return 1;
}
I am writing a simple multi-threaded client-server UDP program in C where I send multiple messages at once to the server, and wait for the replies in my receive thread. I'm doing this in order to test the time packets are sent and received.
I have tested locally with my server with 10 packets, and I am correctly receiving all 10 packets, at which point my program terminates.
However, when I test my client with a remote server, my program hangs after I receive about 6 packets. I know the program is hanging on the recvfrom() call, but I don't know why.
I have tried changing the parameters in the call and putting the call in the while loop itself, but to no avail.
Here is my client code:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <pthread.h>
#include <sys/time.h>
#define SERVER_IP "127.0.0.1"
#define PORT 7851
#define DATA_SIZE 99
#define NUM_MSGS 10
// function declaration for connection handler
void *connection_handler(void *);
struct timeval times[NUM_MSGS][2];
struct sockaddr_in serverAddress;
int main() {
int socketFd;
char buf[DATA_SIZE];
//struct sockaddr_in serverAddress;
char msg[DATA_SIZE];
int size, numSent;
time_t timeSent;
pthread_t threadId;
// Create the socket
if ((socketFd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
perror("Socket creation failure");
exit(-1);
}
// Initialize server information
serverAddress.sin_family = AF_INET;
serverAddress.sin_addr.s_addr = inet_addr(SERVER_IP);
serverAddress.sin_port = htons(PORT);
// Print server information
printf("IP address of server is: %s\n", inet_ntoa(serverAddress.sin_addr));
printf("Server port is: %d\n", (int) ntohs(serverAddress.sin_port));
// Create new thread to handle received messages from server
if (pthread_create(&threadId, NULL, connection_handler, (void *)&socketFd) < 0) {
perror("Thread creation failure");
exit(-1);
}
numSent = 0;
int i, j, n;
for (i = 0; i < NUM_MSGS; i++) {
// Get current time and create message
gettimeofday(×[i][0], NULL);
n = snprintf(msg, DATA_SIZE, "%d", numSent);
msg[n] = '\0';
if (n < 0 || n > DATA_SIZE) {
perror("Message creation failure");
}
// Send msg to server
size = sendto(socketFd, (char *)msg, strlen(msg), 0, (struct sockaddr *) &serverAddress, sizeof(serverAddress));
// Check for sendto error
if (size == -1) {
perror("sendto failure");
exit(-1);
}
printf("Client message %d sent.\n", numSent);
numSent++;
}
// Wait for straggler replies
sleep(2);
pthread_join(threadId, NULL);
//print out times
for (i = 0; i < NUM_MSGS; i++){
for (j = 0; j < 2; j++){
printf("[%d][%d] = [%ld.%06ld]\n", i, j, (long int)(times[i][j].tv_sec), (long int)(times[i][j].tv_usec));
}
}
close(socketFd);
return 0;
}
// Connection handler function for new thread created to receive server replies
void *connection_handler(void *newSocketPtr) {
// cast newSocketPtr to integer ptr then dereference to get the socketFd
int socketFd = *(int *)newSocketPtr;
char buf[DATA_SIZE];
int addrLen, size;
int numReceived = 0;
time_t timeSent, timeReceived, diff, totalTime, avgRTT;
addrLen = sizeof(serverAddress);
while ((size = recvfrom(socketFd, (char *)buf, DATA_SIZE, 0, (struct sockaddr *) &serverAddress, &addrLen))!= -1){ // What about when packets get dropped???
printf("Expecting packet %d\n", numReceived+1);
// Check for recvfrom error
if (size == -1){
perror("recvfrom failure");
exit(-1);
}
buf[size] = '\0';
// Get current time
gettimeofday(×[atoi(buf)][1], NULL);
printf("Message received from server: %s\n", buf);
if (numReceived == NUM_MSGS - 1)break;
numReceived++;
printf("num received is %d\n", numReceived);
}
close(socketFd);
pthread_exit(NULL);
}
[...] tested locally with my server with 10 packets [...] test my client with a remote server, my program hangs after I receive about 6 packets.
UDP simply does not guarantee that packets will be delivered. Your remote server was to slow and missed four packets.
Here is a simple echo program using sockets and multi threads, it compiles and runs well in my Ubuntu if the client(via telnet) and server run on the same machine, but when I remotely connect to the server via telnet from another machine, it initially runs well(echos my message back every time), but some time later, there is no echo anymore even the telnet session is still alive, i am not sure where the problem is, can someone give some hits on this? I am new to multi thread programming and socket programming, learning on that.
#define ERROR -1
#define MAX_CLIENTS 2
#define MAX_DATA 1024
void* worker(void* sockId)
{
int socketId = *(int*)sockId;
int data_len = 1;
char data[MAX_DATA];
while(data_len > 0)
{
data_len = recv(socketId, data, MAX_DATA, 0);
if (data_len > 0)
{
send(socketId, data, data_len, 0);
data[data_len] = '\0';
printf("Sent message: %s", data);
}
}
printf("Client disconnected\n");
close(socketId);
}
int main(int argc, char* argv[])
{
if (argc <= 1)
{
printf("missing argument: port\n");
exit(-1);
}
struct sockaddr_in server;
struct sockaddr_in client;
int sock;
int new_connection;
int sockaddr_len = sizeof(struct sockaddr_in);
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == ERROR)
{
perror("server socket: ");
exit(-1);
}
server.sin_family = AF_INET;
server.sin_port = htons(atoi(argv[1]));
server.sin_addr.s_addr = INADDR_ANY;
bzero(&server.sin_zero, 8);
if ((bind(sock, (struct sockaddr*)&server, sockaddr_len)) == ERROR)
{
perror("bind: ");
exit(-1);
}
if ((listen(sock, MAX_CLIENTS)) == ERROR)
{
perror("listen: ");
exit(-1);
}
while(1)
{
if ((new_connection = accept(sock, (struct sockaddr*)&client, &sockaddr_len)) == ERROR)
{
perror("accpet: ");
exit(-1);
}
printf("New Client connected from port: %d and IP: %s\n", ntohs(client.sin_port), inet_ntoa(client.sin_addr));
pthread_t thread;
pthread_create(&thread, NULL, worker, (void*)&new_connection);
pthread_detach(thread);
}
close(sock);
pthread_exit(NULL);
return 0;
}
Add some logging and you'll probably find that your code is blocked in send. You use naive, sequential I/O, so if the other end of the connection stops reading data, soon you do too.
I have a text book TCP server. In which I am using accept function on an active socket. Note: I have commented out the call to listen on listenfd in main.
#include <stdlib.h>
#include <stdio.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <errno.h>
#include <string.h>
void do_work(int sockfd, int lisfd)
{
printf("Child's process id is %d\n", getpid());
close(lisfd);
const int MAXLINE = 30;
char buff[MAXLINE];
time_t ticks;
ticks = time(NULL);
snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks));
write(sockfd, buff, strlen(buff));
close(sockfd);
exit(0);
}
//argc and argv include the program name itself too in the count and array
int main(int argc, char** argv[])
{
int listenfd, connfd;
const int IPLEN = 50;
//max number of connections that server can handle simultaneously
const int LISTENQ = 10;
struct sockaddr_in servaddr,cliaddr;
char cliip[IPLEN];
socklen_t len;
const int PORT = 8088;
if ((listenfd = socket(AF_INET, SOCK_STREAM, 0) ) < 0)
{
printf("listenning socket error %s\n", strerror(errno));
exit(-1);
}
//initialize sockaddr stuctures to zero
bzero(&cliaddr, sizeof(cliaddr));
bzero(&servaddr, sizeof(servaddr));
//initialize value-result argument to accept
len = sizeof(cliaddr);
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(PORT);
// INADDR_ANY means that socket bound to this servaddr can accept connection
// from any of the interface available on the system
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0)
{
printf("bind error %s\n", strerror(errno));
exit(-1);
}
//listen(listenfd, LISTENQ);
printf("Parent's process id is %d\n", getpid());
for (int i = 0; i < 2; i++)
//for(;;)
{
connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &len);
printf("accepting connection from ip %s on port %lu\n",
inet_ntop(AF_INET, &cliaddr.sin_addr, &cliip, sizeof(cliip)), ntohl(cliaddr.sin_port));
pid_t childpid;
if ((childpid = fork()) == 0)
{
do_work(connfd,listenfd);
}
// if you don't close it here, then connfd shall remain open in parent process and EOF shall not be issued as FIN segment shall not be sent by tcp
close(connfd);
}
}
Now when I connect to it through a simple client, it gives me an output like this.
Parent's process id is 11145
accepting connection from ip 0.0.0.0 on port 0
accepting connection from ip 0.0.0.0 on port 0
Child's process id is 11146
Child's process id is 11147
What I want to understand is: what does 0.0.0.0 means here? (Google says that this means that there is no tcp/ip connection here.) But I am not able to put it into perspective. Any help please?
Most propably the call to accept() failed.
You shall test whether accept() returned -1 prior to looking into cliaddr.
Also the code you show close()es the listing socket (down in do_Work()) after the first accept(). Any following accept() though will surely fail.I missed the call to fork()
As per Duck's comment:
However as long as the call to listen() is commented out accept() has to fail.
EDIT: the code below has been fixed to receive and send properly AND to account for the actual bytes of messages sent annd recieved (latter thanks to EJP)
I'm programming with C in Unix.
I have server and client that are supposed to exchange msgs. While client seems to send messages fine, server doesn't receive the messages the client is sending. I've tried using recv() and read() (i know they are practically the same thing but with extra flags on recv()) but I have no luck and I'm not really sure what the problem really is.
I put sleep(3) in the client code after every time it sends a message but i see that once client and server are connected, server immediately closes without waiting for the incoming messages. What am i doing wrong?
This is the client-side code:
#define SERVER_TCP_PORT 11112
#define MAX_DATA_SIZE 500
int main(int argc, char * argv[])
{
int sockfd;
char * host;
char msg[MAX_DATA_SIZE];/* = "get my msg!\n";*/
int msg_len;
struct hostent * hp;
struct sockaddr_in client_address, server_address;
printf("y halo thar\n");
// looking up from the host database
if (argc == 2)
host = argv[1];
else
exit(1);
printf("sdf\n");
hp = gethostbyname(host);
if (!hp)
exit(1);
printf("host found\n");
// setting up address and port structure information
bzero((char * ) &server_address, sizeof(server_address)); // copy zeroes into string
server_address.sin_family = AF_INET;
bcopy(hp->h_addr, (char *) &server_address.sin_addr, hp->h_length);
server_address.sin_port = htons(SERVER_TCP_PORT);
printf("set\n");
// opening up socket
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0 )
exit(1);
printf("opened\n");
// connecting
if (connect(sockfd, (struct sockaddr *) &server_address, sizeof(server_address)) < 0)
exit(1);
printf("connected\n");
int i;
for (i = 0; i < MAX_DATA_SIZE; ++i)
{
msg[i] = '.';
}
msg[MAX_DATA_SIZE-1] = '\0';
for(i = 0; i < 11; i++)
{
// send message to connected socket
msg_len = write(sockfd, msg, MAX_DATA_SIZE);
if(msg_len < 1)
printf("notsent\n");
else
printf("%i bytes sent\n", msg_len);
// recieve messages from connected socket
msg_len = read(sockfd, msg, MAX_DATA_SIZE);
if (msg_len < 1)
printf("not recieved\n");
else
{
printf("%i bytes received\n", msg_len);
printf(msg);
printf("\n");
}
}
// close connection
close(sockfd);
printf("closed\n");
}
and this is the server side
#define SERVER_TCP_PORT 11112
#define MAX_DATA_SIZE 500
int main()
{
printf("o halo thar\n");
int sockfd, new_sockfd;
int client_addr_len;
char msg [MAX_DATA_SIZE];
int msg_len;
char got_msg [11] = "got ur msg\0";
struct sockaddr_in server_address, client_address;
// setting up address and port structure information
bzero((char * ) &server_address, sizeof(server_address)); // copy zeroes into string
server_address.sin_family = AF_INET;
server_address.sin_addr.s_addr = htonl(INADDR_ANY);
server_address.sin_port = htons(SERVER_TCP_PORT);
// opening up socket
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0 )
exit(1);
printf("socket is opened\n");
// binding
if (bind(sockfd, (struct sockaddr *) &server_address, sizeof(server_address)) < 0)
exit(1);
printf("socket is bound\n");
// listening
listen(sockfd,5);
printf("listening\n");
// block and wait for an incoming connection
client_addr_len = sizeof(client_address);
new_sockfd = accept(sockfd, (struct sockaddr *) &client_address, &client_addr_len);
if (new_sockfd < 0)
exit(1);
printf("accepted\n");
int i;
for( i = 0; i < 11; i++)
{
// recieve messages from connected socket
printf("waiting\n");
msg_len = read(new_sockfd, msg, MAX_DATA_SIZE);
if (msg_len < 1)
{
printf("no msg recieved\n");
}
else
{
printf("bytes recieved: %i\n", msg_len);
}
// send message to connected socket
msg_len = write(new_sockfd, got_msg, sizeof(got_msg));
if (msg_len < 1)
printf("not sent\n");
else
printf("%i bytes sent\n", msg_len);
}
// close connection
close(sockfd);
printf("socket closed. BYE! \n");
}
In the server code, the problem is on this line:
msg_len = read(sockfd, msg, MAX_DATA_SIZE);
You are calling read on sockfd, but you need to call read or recv on new_sockfd (the socket returned by accept()). new_sockfd is the one that's connected to the client (sockfd is used to accept further connections - eg if another client connects).
You should read from the socket returned by accept.
Try to call read on the socket returned from accept.
Receiver Side:
while(1)
{
len=read(sd,buff,sizeof(buff));
if(len==0)
{
//End of File receving.
break;
}
else
{
st=fwrite(buff,sizeof(char),len,fp);
}
}
Send Side:
while(!feof(fp))
{
len=fread(buff,sizeof(char),MW,fp);
if(len==0)
{
//EOF
st=write(cd,&d,sizeof(int));
break;
}
else
{
st=write(cd,buff,len);
}
}
is the implementation based on stream or datagram?
there are some problem with your operation flow. the server might start to read before client send anything.
since client and server are separated, you can imagine them running concurrently.
right after your server side "accept" connection request, there might be possibly some handshake overhead occurs or network delays causing server app to execute ahead in time, attempt to extract data but meet with errors (no data received yet).
you can try this out by adding sleep in server code after accept connection, where client should have enough time to send the data.
another better solution is to make data retrieval cope with empty buffer or asynchronous read.