How do you send more than one message through a socket?

My client connects to my server program, I send a message which appears on the server and then when I enter another message to send, the server doesn't display it. Is the message actually being sent? How do I find out?

I don't understand why. Could the socket blocked be blocked? How do I send and receive messages without connecting, sending a message and then closing a socket as that is the only other way I can think of.
Any help would be most grateful. Know any sites that answer these questions?
I've looked everywhere for info, but no one seems to have done this before. In no books or on any websites.

Jon.

Both client and the server programs are listed below. Ive taken out most of the crap, their might be some left. Might as well be the programs themselves!
Anyway...

Client program below (I like tabbing ;)
====================

// client program v0.01
#include // for printf(), fprintf() and perror()
#include // for isupper()
#include // for socket(), connect(), send() and recv()
#include // for sockaddr_in and inet_ntoa()
#include // for getchar(), atoi() and exit()
#include // for memset()
#include // for fcntl()
#include // for sigaction()
#include // for errno
#include // for close()
#include "wrapper.h" // my message wrapper

#define MAX_NAME 20 // max name length
#define MAX_PASS 10 // max password length

#define TEMP_CLIENT 3 // this macro only temporary

// Global Constants

struct profile{ // users profile info
unsigned short registered;
unsigned long userID;
char username[MAX_NAME];
char password[MAX_PASS];
unsigned short status;
}Profile;

struct server{ // server address info
int sock; // socket descriptor
char *IPaddr; // server IP address
unsigned short port; // server port
} Server;

struct sockaddr_in servAddr; // server address

msgStr msgWrite;
msgStr msgRead;

typedef unsigned short bool;

// Function declarations
void ErrorHandler(char *errMsg); // error handling function
void SignalHandler(int signalType);
void ConnectToServer(void); // connect to server
void CloseServer(void);
void SendMsg(unsigned short type,unsigned int from,unsigned int to,void *msg);
void RecvMsg(void);
void ProcessMsgType(unsigned short type);
bool AmIRegistered(void);
void RegisterMe(void);
void PrintMenu(void);
void GetString(char *str);
short int ValidateStr(char *str,int length);

int main (int argc, char *argv[])
{
int option; // menu option
char *message;
struct sigaction handler;

// temporary!!! But remember to add 'demo' as an argument to enable demonstration functionality
if (argc<2) // test for correct number of arguments
{
fprintf(stderr,"Usage: %s <Server IP>
",argv[0]);
exit(1);
}
Server.IPaddr=argv[1];
Server.port=atoi(argv[2]);

ConnectToServer(); // connect client to server
Profile.status=1; // signed in user
printf("
Client signed in.
");

// set SignalHandler() as handler function
handler.sa_handler=SignalHandler;
// create mask that masks all signals
if (sigfillset(&handler.sa_mask)<0)
ErrorHandler("sigfillset() failed");
// no flags
handler.sa_flags=0;

// set signal handling for interrupt signals
if (sigaction(SIGINT,&handler,0)<0)
ErrorHandler("sigaction() failed for SIGINT");
if (sigaction(SIGPIPE,&handler,0)<0)
ErrorHandler("sigaction() failed for SIGPIPE");

while (option!=9) {
PrintMenu(); // display menu
fflush(stdin);
scanf("%d",&option); // wait for input
switch(option)
{
case 1: {
if (Profile.status==1)
{
CloseServer();
Profile.status=0; // sign out user
//exit(0);
printf("
Client signed out.
");
}
else
{
ConnectToServer();
Profile.status=1;
printf("
Client signed in.
");
}
} break;
case 3: {
printf("
Enter message:");
if ((message=calloc(MAX_LENGTH,sizeof(char)))==NULL) // allocate memory for pointer array
ErrorHandler("calloc() failed");
fflush(stdin);
GetString(message); // enter message to send
printf("Msg to send: %s",message); // debug code
SendMsg(TEXT_MESSAGE,TEMP_CLIENT,5,(char *)message);
printf("
After SendMsg()"); // debug code
free(message); // return memory after use
printf("
Freed message"); // debug code
}break;
default: break;
}
}
//}
// close connection(s)
CloseServer();
exit(0);
}

void SignalHandler(int signalType)
{
switch(signalType)
{
case SIGINT: {
printf("
Received interrupt signal. Exiting.
");
CloseServer();
exit(0);
} break;
case SIGIO: {
printf("
Received Message:
");
RecvMsg();
printf("
After RecvMsg()"); // debug code
//if (errno!=EWOULDBLOCK)
// ErrorHandler("
...end message.
");

} break;
case SIGPIPE: {
printf("
Cannot connect to server.
");
} break;
default: printf("
Unknown signal received. Ignoring.
");
}
}

void SendMsg(unsigned short type,unsigned int from,unsigned int to,void *msg)
{
int size;

printf("
Before - %u %u %u %s",type,from,to,msg); // debug code
// change byte order from host to network
msgWrite.msgType=htons(type);
msgWrite.from=htonl(from);
msgWrite.to=htonl(to);
strcpy(msgWrite.message,msg);
printf("
After - %u %u %u %s",ntohs(msgWrite.msgType),ntohl(msgWrite.from),ntohl(msgWrite.to),msgWrite.message); // debug code

size=sizeof(msgWrite);
if (send(Server.sock,&msgWrite,size,0)!=size)
ErrorHandler("send() sent a different number of bytes than expected");
printf("
Message sent");
}

void RecvMsg(void)
{
int totalBytesRcvd; // total number of bytes received
int bytesRcvd; // no of bytes received
void *buffer=(void *) &msgRead;

printf("
Before recv() message"); // debug code
for (totalBytesRcvd=0;totalBytesRcvd<sizeof(msgRead); totalBytesRcvd+=bytesRcvd)
{
if ((bytesRcvd=recv(Server.sock,buffer+totalBytesRcvd,sizeof(msgRead)-totalBytesRcvd,0))<=0)
ErrorHandler("recv() failed or connection closed prematurely");
}

// change byte order from network to host
msgRead.msgType=ntohs(msgRead.msgType);
msgRead.from=ntohl(msgRead.from);
msgRead.to=ntohl(msgRead.to);

printf("
RecvMsg: %s",msgRead.message); // debug code
ProcessMsgType(msgRead.msgType);
printf("
After ProcessMsgType."); // debug code
}

void ProcessMsgType(unsigned short type)
{
switch(type)
{
case TEXT_MESSAGE: printf("
In ProcessMsgType: %s
",msgRead.message); break;
case TEXT_MESSAGE_RCVD: printf("
Message received."); break;
default: break;
}
}

void GetString(char *str)
{
char c;
int i=0;

c=getchar(); // start entry of characters
while((c=getchar())!='
') // enter character until end of newline
{
str[i]=c; // add charcater to array
i++;
}
str[i]=''; // add terminator to string
}

void ConnectToServer(void)
{
// create stream socket using TCP
if ((Server.sock=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP))<0)
ErrorHandler("socket() failed");

// construct server address structure
memset(&servAddr,0,sizeof(servAddr)); // zero out structure
servAddr.sin_family=AF_INET; // internet address family
servAddr.sin_addr.s_addr=inet_addr(Server.IPaddr); // server IP address
servAddr.sin_port=htons(Server.port); // server port

// establish connection to server
if (connect(Server.sock,(struct sockaddr *) &servAddr,sizeof(servAddr))<0)
ErrorHandler("connect() failed");
printf("
Connected to server...");
//fcntl(Server.sock,F_SETFL,O_NONBLOCK);
}

void CloseServer(void)
{
close(Server.sock);
shutdown(Server.sock,SHUT_RDWR);
Server.sock=-1;
}

void ErrorHandler(char *errMsg)
{
perror(errMsg);
exit(EXIT_FAILURE);
}

void PrintMenu(void) // display main menu options
{
printf("
Client of Instant Messenger
");
printf("
Server IP: %s Server Port: %d",Server.IPaddr,Server.port);
if (Profile.status==0)
printf("
1 - Sign in");
else
printf("
1 - Sign out");
printf("
3 - Send message");
//printf("
4 - add user");
//printf("
5 - delete user");
printf("
9 - Quit program");
printf("
Enter option: ");
}


server program
==============
// server.c prototype
// v02
#include <stdio.h> // for printf(), fprintf() and perror()
#include // for socket(), bind(), and connect()
#include // for sockaddr_in and inet_ntoa()
#include // for atoi() and exit()
#include // for memset()
#include // close()
#include "server.h" // wrapper tools

#include // for struct timeval {}
#include // for fcntl()

int main(int argc,char *argv[])
{
int *servSock; // socket descriptor for server
int maxDescriptor; // max socket descriptor value
fd_set sockSet; // set of socket descriptors for select()
long timeout; // timeout value given on command line
struct timeval selTimeout; // timeout for select()
int running=1; // 1 if server should be running; 0 otherwise
int noPorts; // number of ports specified on command line
int port; // looping variable for ports
unsigned short portNo; // actual port number

if (argc<3) // temporarily test for correct number of arguments. But remember to add 'demo' as an argument to enable demonstration functionality
{
fprintf(stderr,"Usage: %s <Timeout (secs.)> ...
",argv[0]);
exit(1);
}

timeout=atoi(argv[1]); // first arg: timeout (secs)
noPorts=argc-2; // number of ports is argument count minus 2

// allocate list of sockets for incoming connections
servSock=(int *) malloc(noPorts * sizeof(int));
// initialise maxDescriptor for use by select()
maxDescriptor=-1;

// create list of ports and sockets to handle ports
for (port=0; portmaxDescriptor)
maxDescriptor=servSock[port];
}

printf("Starting server: Hit return to shutdown
");
while(running)
{
// zero socket descriptor vector and set for server sockets
// this must be reset every time select() is called
FD_ZERO(&sockSet);
printf("Reset socket descriptor.
"); // debug code
// add keyboard to descriptor vector
FD_SET(STDIN_FILENO,&sockSet);
printf("Added keyboard to descriptor vector.
"); // debug code
for (port=0; port<noPorts; port++)
FD_SET(servSock[port],&sockSet);

//printf("Did set port for loop.
"); // debug code
// timeout specification
// this must be reset every time select() is called
//selTimeout.tv_sec=timeout; // timeout (secs.)
//selTimeout.tv_usec=0; // 0 microseconds
printf("Ready to accept input. Waiting with select().
"); // debug code
// suspend program until descriptor is ready or timeout
if (select(maxDescriptor+1,&sockSet,NULL,NULL,NULL)==0)
printf("No echo requests for %ld secs...Server still alive
",timeout);
else
{
if (FD_ISSET(STDIN_FILENO,&sockSet)) // check keyboard
{
printf("Shutting down server
");
getchar();
running=0;
}

for (port=0; port<noPorts; port++)
if (FD_ISSET(servSock[port],&sockSet))
{
printf("Request on port %d:
",port);
DealWithClient(AcceptConnection(servSock[port]));
printf("
Dealt with client.
"); // debug code
}
printf("After port list.
"); // debug code
}
printf("After if.
"); // debug code

}

// close sockets
for (port=0; port<noPorts; port++)
close(servSock[port]);

// free list of sockets
free(servSock);

exit(0);
}

int CreateServerSocket(unsigned short port)
{
int sock;
int yes=1;
struct sockaddr_in servAddr; // local address

// create socket for incoming connections
if ((sock=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP))<0)
ErrorHandler("socket() failed");

// construct local address structure
memset(&servAddr,0,sizeof(servAddr)); // zero out structure
servAddr.sin_family=AF_INET; // internet address family
servAddr.sin_addr.s_addr=htonl(INADDR_ANY); // any incoming interface
servAddr.sin_port=htons(port); // local port

// stop "address already in use" error message appearing
if (setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int))== -1)
ErrorHandler("setsockopt() failed");

// bind to local address
if (bind(sock,(struct sockaddr *) &servAddr,sizeof(servAddr))<0)
ErrorHandler("bind() failed");

// mark the socket so it will listen for incoming connections
if (listen(sock,MAXPENDING)<0)
ErrorHandler("listen() failed");

return sock;
}

int AcceptConnection(int servSock)
{
int clntSock;
unsigned int clntLen; // length of client address structure
struct sockaddr_in clntAddr; // client address

// set the size of the in-out parameter
clntLen=sizeof(clntAddr);

// wait for a client to connect
if ((clntSock=accept(servSock,(struct sockaddr *) &clntAddr,&clntLen))<0)
ErrorHandler("accept() failed");

// clntSock is connected to a client!
printf("
Handling client %s
",inet_ntoa(clntAddr.sin_addr));

return clntSock;
}

void ErrorHandler(char *errMsg)
{
perror(errMsg);
exit(1);
}

void DealWithClient(int sock)
{
RecvMsg(sock);

// temporary
readMsg.msgType=ntohs(readMsg.msgType);
temp=ntohl(readMsg.from);
readMsg.from=ntohl(readMsg.to);
readMsg.to=temp;

ProcessMsgType(readMsg.msgType);*/

printf("
After received."); // debug code
close(sock); // close client socket
shutdown(sock,SHUT_RDWR);
printf("
%d socket closed",sock); // debug code
}

void ProcessMsgType(unsigned short type)
{
//FILE *fptr;
char *name,*pass;
switch(type)
{
case TEXT_MESSAGE: {
printf("
Received Message: %s
",readMsg.message);
} break; // check through array of user database for id number and if online send message, otherwise report back saying user not online.
default: printf("
Unknown message received.
");
}
}

void RecvMsg(int sock)
{
int totalBytesRcvd; // total number of bytes received
int bytesRcvd; // no of bytes received
void *buffer=(void *) &readMsg;

totalBytesRcvd=0;
while (totalBytesRcvd<sizeof(readMsg))
{
if ((bytesRcvd=recv(sock,buffer+totalBytesRcvd,sizeof(readMsg)-totalBytesRcvd,0))<=0)
ErrorHandler("recv() failed or connection closed prematurely");
totalBytesRcvd+=bytesRcvd;
}

// change byte order from network to host
readMsg.msgType=ntohs(readMsg.msgType);
readMsg.from=ntohl(readMsg.from);
readMsg.to=ntohl(readMsg.to);

ProcessMsgType(readMsg.msgType);
}

Comments

  • : My client connects to my server program, I send a message which appears on the server and then when I enter another message to send, the server doesn't display it. Is the message actually being sent? How do I find out?

    I'm not big specialist in it, but I did client/server just for fun. Try to rebuid your server, that every time it accepts connection, it is making fork(). Then u need to check either it is child process & to proceed connection, either it is parent, then close socket.

    Right now I have no example, but for fork it is like this

    switch( fork() ){
    case -1: cout << "Error!
    "; // Of course need to write (pid_t)-1,but :)
    break;
    case 0: break; // Child
    default: break; // Parent
    }

    : I don't understand why. Could the socket blocked be blocked? How do I send and receive messages without connecting, sending a message and then closing a socket as that is the only other way I can think of.
    : Any help would be most grateful. Know any sites that answer these questions?
    : I've looked everywhere for info, but no one seems to have done this before. In no books or on any websites.
    :
    : Jon.

Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories

In this Discussion