I have been working on this for a while trying to learn socket programming but am running into some probably bone-headed problems.
The problem that I am trying to solve is sending 3 identical sends from the client to the server for the purpose of registering the client. At this point I have one of the sends and receives working but am not able to get the second or third to work. For debugging purposes I am printing the data field of my packet struct and, while it prints for the first receive, the second receive is blank and the third receive is an odd squiggly box followed by an equals sign. I think I am getting stuck in the first receive maybe but I am really not sure what the issue is.
In the following code I have attempted to send the same packet over 3 times, and have also tried what I currently have below, sending 3 different packets that should all contain the same info, the result is always the same.
Here is the code for the client:
#include<stdio.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<netdb.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.h>
#define SERVER_PORT 5654
#define MAX_LINE 256
/*structure of the packet*/
struct packet{
short type;
char data[MAX_LINE];
};
int main(int argc, char* argv[])
{
struct packet packet_reg;
struct packet packet_reg2;
struct packet packet_reg3;
struct hostent *hp;
struct sockaddr_in sin;
char *host;
char buf[MAX_LINE];
int s;
int len;
char hostname[1024];
hostname[1023] = '\0';
if(argc == 2){
host = argv[1];
}
else{
fprintf(stderr, "usage:newclient server\n");
exit(1);
}
/* translate host name into peer's IP address */
hp = gethostbyname(host);
if(!hp){
fprintf(stderr, "unkown host: %s\n", host);
exit(1);
}
/* active open */
if((s = socket(PF_INET, SOCK_STREAM, 0)) < 0){
perror("tcpclient: socket");
exit(1);
}
/* build address data structure */
bzero((char*)&sin, sizeof(sin));
sin.sin_family = AF_INET;
bcopy(hp->h_addr, (char *)&sin.sin_addr, hp->h_length);
sin.sin_port = htons(SERVER_PORT);
if(connect(s,(struct sockaddr *)&sin, sizeof(sin)) < 0){
perror("tcpclient: connect");
close(s);
exit(1);
}
/* main loop: get and send lines of text */
while(fgets(buf, sizeof(buf), stdin)){
gethostname(hostname, 1023);
printf("Hostname: %s\n", hostname);
packet_reg.type = htons(121);
strcpy(packet_reg.data,hostname);
/*send the registration packet to the server*/
if(send(s,&packet_reg,sizeof(packet_reg),0)<0){
printf("\nsend failed\n");
exit(1);
}
packet_reg2.type = htons(121);
strcpy(packet_reg2.data,hostname);
printf("%s\n",packet_reg2.data );
/*send the registration packet to the server*/
if(send(s,&packet_reg2,sizeof(packet_reg2),0)<0){
printf("\nsend failed\n");
exit(1);
}
packet_reg3.type = htons(121);
strcpy(packet_reg3.data,hostname);
/*send the registration packet to the server*/
if(send(s,&packet_reg3,sizeof(packet_reg3),0)<0){
printf("\nsend failed\n");
exit(1);
}
}
}
Here is the code for the server, I have done the same thing with trying to print the same packet and replace the information in it as well as use 3 different packets.
#include<stdio.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<netdb.h>
#include<string.h>
#include<stdlib.h>
#define SERVER_PORT 5654
#define MAX_LINE 256
#define MAX_PENDING 5
/*structure of the packet*/
struct packet{
short type;
char data[50];
};
int main(int argc, char* argv[])
{
struct packet packet_reg;
struct packet packet_reg2;
struct packet packet_reg3;
struct sockaddr_in sin;
struct sockaddr_in clientAddr;
char buf[MAX_LINE];
int s, new_s;
int len;
/* setup passive open */
if((s = socket(PF_INET, SOCK_STREAM, 0)) < 0){
perror("tcpserver: socket");
exit(1);
}
/* build address data structure */
bzero((char*)&sin, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = INADDR_ANY;
sin.sin_port = htons(SERVER_PORT);
if(bind(s,(struct sockaddr *)&sin, sizeof(sin)) < 0){
perror("tcpclient: bind");
exit(1);
}
listen(s, MAX_PENDING);
/* wait for connection, then receive and print text */
while(1){
if((new_s = accept(s, (struct sockaddr *)&clientAddr, &len)) < 0){
perror("tcpserver: accept");
exit(1);
}
printf("\n Client's port is %d \n", ntohs(clientAddr.sin_port));
if(recv(new_s,&packet_reg,sizeof(packet_reg),0)<0){
printf("\ncouldnt receive first reg packet\n");
exit(1);
}
printf("%s\n",packet_reg.data );
if(recv(new_s,&packet_reg2,sizeof(packet_reg2),0)<0){
printf("\not recieved second reg packet\n");
exit(1);
}
printf("%s\n",packet_reg2.data );
if(recv(new_s,&packet_reg3,sizeof(packet_reg3),0)<0){
printf("\ncouldnt receive first reg packet\n");
exit(1);
}
printf("%s\n",packet_reg3.data );
}
}
Any help on this would be greatly appreciated. I am sure it is a dumb error and that I am just not understanding how it works. First time using c.
recv()fills the buffer. It isn't obliged to do that. You have to loop. You're also not checking for end of stream, and you're not closing any sockets.