TCP Echo Server Using thread command line not showing - c++

In my project wants when client side write like LIST the server side will directory list documents and after when I write like GET filename.txt but in the server side not shows me any thing ı think is stop how can I solve this problem my project describer in photo enter image description here
enter image description here
source code is
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
#include <sys/wait.h>
#include <sys/socket.h>
#include <resolv.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <stdbool.h>
#include <dirent.h>
/* Definations */
#define DEFAULT_BUFLEN 1024
#define PORT 1888
void PANIC(char* msg);
#define PANIC(msg) { perror(msg); exit(-1); }
bool StartsWith(const char *a, const char *b)
{
if(strncmp(a, b, strlen(b)) == 0) return 1;
return 0;
}
void* Child(void* arg)
{ char line[DEFAULT_BUFLEN];
int bytes_read;
int client = *(int *)arg;
send(client,"Welcome to Vepa Server\n",strlen("Welcome to Vepa Server\n"),0);
do
{
bytes_read = recv(client, line, sizeof(line), 0);
if (bytes_read > 0) {
printf("%s",line);
// list command in here
if (strcmp(line,"LIST\n") ==0)
{
while(1)
{
DIR *d;
struct dirent *dir;
d = opendir(".");
if (d) {
while ((dir = readdir(d)) != NULL) {
send(client,dir->d_name,strlen(dir->d_name),0);
send(client,"\n",strlen("\n"),0);
}
closedir(d);
}
return(0);
}
}
if (StartsWith(line,"GET") == 1)
{
printf(line);
}
if ( (bytes_read=send(client, line, bytes_read, 0)) < 0 ) {
printf("Send failed\n");
break;
}
} else if (bytes_read == 0 ) {
printf("Connection closed by client\n");
break;
} else {
printf("Connection has problem\n");
break;
}
} while (bytes_read > 0);
close(client);
return arg;
}
int main(int argc, char *argv[])
{
int sd,opt,optval;
struct sockaddr_in addr;
unsigned short port=0;
while ((opt = getopt(argc, argv, "p:")) != -1) {
switch (opt) {
case 'p':
port=atoi(optarg);
break;
}
}
if ( (sd = socket(PF_INET, SOCK_STREAM, 0)) < 0 )
PANIC("Socket");
addr.sin_family = AF_INET;
if ( port > 0 )
addr.sin_port = htons(port);
else
addr.sin_port = htons(PORT);
addr.sin_addr.s_addr = INADDR_ANY;
// set SO_REUSEADDR on a socket to true (1):
optval = 1;
setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof optval);
if ( bind(sd, (struct sockaddr*)&addr, sizeof(addr)) != 0 )
PANIC("Bind");
if ( listen(sd, SOMAXCONN) != 0 )
PANIC("Listen");
printf("System ready on port %d\n",ntohs(addr.sin_port));
while (1)
{
int client, addr_size = sizeof(addr);
pthread_t child;
client = accept(sd, (struct sockaddr*)&addr, &addr_size);
printf("Connected: %s:%d\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
if ( pthread_create(&child, NULL, Child, &client) != 0 )
perror("Thread creation");
else
pthread_detach(child); /* disassociate from parent */
}
return 0;
}

Related

simple multicast app not working on different computer on the same network

If I launch 2 instances of the code below in the same computer the multicast works fine.
If I launch it on a different computer in the same network I won't receive anything.
Any idea what could be wrong? This code should compile as is.
I am testing on win10 but I get similar results when I run this on linux.
#include "pch.h"
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include "winsock2.h"
#include <iostream>
#include <conio.h>
#include <thread>
#include <ws2tcpip.h>
#pragma comment(lib, "ws2_32.lib")
char mcastGroup[] = "224.1.2.3";
int mcastPort = 5435;
int CreateSocket()
{
return socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
}
void JoinGroup(int sck)
{
struct ip_mreq grp;
grp.imr_multiaddr.s_addr = inet_addr(mcastGroup);
grp.imr_interface.s_addr = htonl(INADDR_ANY);
if (setsockopt(sck, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&grp, sizeof(grp)) < 0)
{
printf("Error in joining group\n");
closesocket(sck);
exit(1);
}
}
int receiver()
{
int sck = CreateSocket();
int reuse = 1;
if (setsockopt(sck, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse, sizeof(reuse)) < 0)
{
perror("Socket reuse address error\n");
closesocket(sck);
exit(1);
}
JoinGroup(sck);
struct sockaddr_in lclSck;
memset((char *)&lclSck, 0, sizeof(lclSck));
lclSck.sin_family = AF_INET;
lclSck.sin_port = htons(mcastPort);
lclSck.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(sck, (struct sockaddr*)&lclSck, sizeof(lclSck)))
{
perror("Error in binding socket\n");
closesocket(sck);
exit(1);
}
while (1)
{
int blen;
char buf[1024];
blen = sizeof(buf);
memset(buf, 0, blen);
struct sockaddr_in addrin;
int addrinlen = sizeof(addrin);
memset(&addrin, 0, sizeof(addrin));
int res = recvfrom(sck, buf, blen, 0, (sockaddr *)&addrin, &addrinlen);
if (res<0)
{
printf("Message read error\n");
closesocket(sck);
exit(1);
}
else
{
printf(": %s\n", buf);
}
}
return 0;
}
int sender()
{
int sck = CreateSocket();
struct in_addr lclInterface;
lclInterface.s_addr = htonl(INADDR_ANY);
if (setsockopt(sck, IPPROTO_IP, IP_MULTICAST_IF, (char *)&lclInterface, sizeof(lclInterface)) < 0)
{
printf("Local interface error\n");
exit(1);
}
else
{
printf("Local interface set\n");
}
u_char ttl = 5;
setsockopt(sck, IPPROTO_IP, IP_MULTICAST_TTL, (char *)&ttl, sizeof(ttl));
while (1)
{
int blen;
char buf[1024];
blen = sizeof(buf);
memset(buf, 0, blen);
for (int i = 0; i < 100; i++)
{
fgets(buf, blen, stdin);
sockaddr_in grpSck;
memset((char *)&grpSck, 0, sizeof(grpSck));
grpSck.sin_family = AF_INET;
grpSck.sin_port = htons(mcastPort);
grpSck.sin_addr.s_addr = inet_addr(mcastGroup);
if (sendto(sck, buf, blen, 0, (struct sockaddr*)&grpSck, sizeof(grpSck)) < 0)
{
printf("Error in sending message");
}
}
}
return 0;
}
int main()
{
WSADATA wsaData;
WSAStartup(MAKEWORD(2, 2), &wsaData);
std::thread t1([&] { receiver(); return 0; });
sender();
WSACleanup();
}
This code should work, the problem was that I was using IP_MULTICAST_IF, that forces to use a network interface different from the default one. In case one needs to use such a thing I was able to get the multicast working by following
Thanks to Remy Lebeau advice, that is to make sure you are binding the sockets to IPs that are in the same network.
Here is working code the code:
#ifdef WIN32
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <winsock2.h>
#include <ws2tcpip.h>
#pragma comment(lib, "ws2_32.lib")
#else
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <unistd.h>
#endif
#include <thread>
char mcastGroup[] = "224.1.2.3";
int mcastPort = 5435;
void PrintAddrIn(sockaddr_in addr_in)
{
char str[255];
inet_ntop(AF_INET, &addr_in.sin_addr, (char *)str, sizeof(str));
printf("%s", str);
}
int receiver(int sck)
{
while (1)
{
char buf[1024];
memset(buf, 0, sizeof(buf));
struct sockaddr_in addrin;
socklen_t addrinlen = sizeof(addrin);
memset(&addrin, 0, sizeof(addrin));
int res = recvfrom(sck, buf, sizeof(buf), 0, (sockaddr *)&addrin, &addrinlen);
if (res<0)
{
printf("Message read error\n");
exit(1);
}
else
{
PrintAddrIn(addrin); printf(": %s\n", buf);
}
}
return 0;
}
int sender(int sck)
{
while (1)
{
sockaddr_in grpSck;
memset((char *)&grpSck, 0, sizeof(grpSck));
grpSck.sin_family = AF_INET;
grpSck.sin_port = htons(mcastPort);
grpSck.sin_addr.s_addr = inet_addr(mcastGroup);
for (int i = 0; i < 100; i++)
{
char buf[1024];
fgets(buf, sizeof(buf), stdin);
if (sendto(sck, buf, strlen(buf), 0, (struct sockaddr*)&grpSck, sizeof(grpSck)) < 0)
{
printf("Error in sending message");
exit(1);
}
}
}
return 0;
}
int main()
{
#ifdef WIN32
WSADATA wsaData;
WSAStartup(MAKEWORD(2, 2), &wsaData);
#endif
int sck = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
// Set reuse
//
int reuse = 1;
if (setsockopt(sck, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse, sizeof(reuse)) < 0)
{
perror("Socket reuse address error\n");
exit(1);
}
else
{
printf("Socket reuse address successfull\n");
}
// Join mcast group
//
struct ip_mreq grp;
grp.imr_multiaddr.s_addr = inet_addr(mcastGroup);
grp.imr_interface.s_addr = htonl(INADDR_ANY);
if (setsockopt(sck, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&grp, sizeof(grp)) < 0)
{
printf("Error in joining group\n");
exit(1);
}
else
{
printf("Group joined successfully\n");
}
// Bind socket
//
struct sockaddr_in lclSck;
memset((char *)&lclSck, 0, sizeof(lclSck));
lclSck.sin_family = AF_INET;
lclSck.sin_port = htons(mcastPort);
lclSck.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(sck, (struct sockaddr*)&lclSck, sizeof(lclSck)))
{
perror("Error in binding socket\n");
exit(1);
}
else
{
printf("Socket binding successfull\n");
}
u_char ttl = 5;
setsockopt(sck, IPPROTO_IP, IP_MULTICAST_TTL, (char *)&ttl, sizeof(ttl));
std::thread t1([&] { receiver(sck); return 0; });
sender(sck);
#ifdef WIN32
WSACleanup();
#endif
}

Multiple Broadcast Reception on Same port but different interfaces

I'm trying to build a little personal DHCP server to serve a specific scope if the broadcast is received on eth0 and another if received on wlan0 but I can't bind more than a single interface on the same address:port combination (255.255.255.255:67)
I heard about SO_REUSABLE but I have no idea about how to implement it and if of course it's the good way to do it
Actually this is my code :
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <netinet/in.h>
#include <errno.h>
#include <fstream>
#include <iostream>
#include <vector>
#define BUFLEN 1024
#define PORT 67
using namespace std;
char *ipAddrFromInterface(char *apInterfaceName) //this function is not from me
{
return "255.255.255.255";
/*char *if_name = (char *) apInterfaceName;
struct ifreq ifr;
size_t if_name_len = strlen(if_name);
if(if_name_len < sizeof(ifr.ifr_name))
{
memcpy(ifr.ifr_name, if_name, if_name_len);
ifr.ifr_name[if_name_len] = 0;
}
else
printf("interface name is too long\n");
int fd = socket(AF_INET, SOCK_DGRAM, 0);
if(fd == -1)
printf("A => %s\n", strerror(errno));
if(ioctl(fd, SIOCGIFADDR, &ifr) == -1)
{
int temp_errno = errno;
close(fd);
printf("B => %s\n", strerror(temp_errno));
}
if(ioctl(fd, SIOCGIFADDR, &ifr) == -1)
{
int temp_errno = errno;
close(fd);
printf("C => %s\n", strerror(temp_errno));
}
close(fd);
struct sockaddr_in* ipaddr = (struct sockaddr_in*) &ifr.ifr_addr;
return inet_ntoa(ipaddr->sin_addr);*/
}
struct socketData
{
int sock;
sockaddr_in socket;
char *interfaceName;
};
void print(int i)
{
printf("%d\n", i);
fflush(stdout);
}
void server_receive_thread(vector<char*> aInterfaceList)
{
int socketIndex = 0;
struct sockaddr_in localSock;
int socketDescriptor; int socketLength;
vector<socketData> aSockets;
for( ; socketIndex < aInterfaceList.size(); socketIndex++)
{
socketData socketD;
char *apInterfaceName = aInterfaceList.at(socketIndex);
if((socketDescriptor = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
{
printf("can't listen on interface %s... sleeping\n", apInterfaceName);
}
else
{
memset(&localSock, 0, sizeof(localSock));
localSock.sin_family = AF_INET;
localSock.sin_port = htons(PORT);
inet_aton(ipAddrFromInterface(apInterfaceName), &localSock.sin_addr);
setsockopt(socketDescriptor, SOL_SOCKET, SO_BINDTODEVICE, apInterfaceName, sizeof(apInterfaceName));
if(bind(socketDescriptor, (struct sockaddr *) &localSock, sizeof(localSock)) == -1)
{
printf("can't bind interface %s to listen on port %d... sleeping\n", apInterfaceName, PORT);
}
else
{
printf("bound to interface %s on port %d\n", apInterfaceName, PORT);
socketD.sock = socketDescriptor;
socketD.socket = localSock;
socketD.interfaceName = apInterfaceName;
aSockets.push_back(socketD);
}
}
}
fd_set master;
int fdMax = -1;
while(1)
{
FD_ZERO(&master);
for(int iSock = 0; iSock < aSockets.size(); iSock++)
{
socketData d = aSockets.at(iSock);
FD_SET(d.sock, &master);
if(d.sock > fdMax)
fdMax = d.sock;
}
printf("fdmax is : ");
print(fdMax);
if(select(fdMax + 1, &master, NULL, NULL, NULL) == -1)
print(2);
print(200);
for(int iSock = 0; iSock < aSockets.size(); iSock++)
{
socketData d = aSockets.at(iSock);
if(FD_ISSET(d.sock, &master))
print(3);
}
print(1);
}
}
int main()
{
std::vector<char*> interfaceList;
interfaceList.push_back("wlan0");
interfaceList.push_back("eth0");
server_receive_thread(interfaceList);
return 0;
}
You don't need a socket per interface. Just bind a single socket to 0.0.0.0 and the desired port. Then it will receive via all interfaces. You certainly can't, and don't need to, bind to 255.255.255.255.
Or, bind it to the single IP address that is connected to the scope you want to serve.

Telnet client error in c++

The telnet client code is :
enter code here
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>
#include <termios.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/telnet.h>
#define DO 0xfd
#define WONT 0xfc
#define WILL 0xfb
#define DONT 0xfe
#define CMD 0xff
#define CMD_ECHO 1
#define CMD_WINDOW_SIZE 31
void negotiate(int sock, unsigned char *buf, int len) {
int i;
if (buf[1] == DO && buf[2] == CMD_WINDOW_SIZE) {
unsigned char tmp1[10] = {255, 251, 31};
if (send(sock, tmp1, 3 , 0) < 0)
exit(1);
unsigned char tmp2[10] = {255, 250, 31, 0, 80, 0, 24, 255, 240};
if (send(sock, tmp2, 9, 0) < 0)
exit(1);
return;
}
for (i = 0; i < len; i++) {
if (buf[i] == DO)
buf[i] = WONT;
else if (buf[i] == WILL)
buf[i] = DO;
}
if (send(sock, buf, len , 0) < 0)
exit(1);
}
static struct termios tin;
static void terminal_set(void) {
// save terminal configuration
tcgetattr(STDIN_FILENO, &tin);
static struct termios tlocal;
memcpy(&tlocal, &tin, sizeof(tin));
cfmakeraw(&tlocal);
tcsetattr(STDIN_FILENO,TCSANOW,&tlocal);
}
static void terminal_reset(void) {
// restore terminal upon exit
tcsetattr(STDIN_FILENO,TCSANOW,&tin);
}
#define BUFLEN 20
int main(int argc , char *argv[]) {
int sock;
struct sockaddr_in server;
unsigned char buf[BUFLEN + 1];
int len;
int i;
if (argc < 2 || argc > 3) {
printf("Usage: %s address [port]\n", argv[0]);
return 1;
}
int port;
if (argc == 3)
port = atoi(argv[2]);
//Create socket
sock = socket(AF_INET , SOCK_STREAM , 0);
if (sock == -1) {
perror("Could not create socket. Error");
return 1;
}
server.sin_addr.s_addr = inet_addr(argv[1]);
server.sin_family = AF_INET;
server.sin_port = htons(port);
//Connect to remote server
if (connect(sock , (struct sockaddr*)&server , sizeof(server)) < 0) {
perror("connect failed. Error");
return 1;
}
puts("Connected...\n");
// set terminal
terminal_set();
atexit(terminal_reset);
struct timeval ts;
ts.tv_sec = 1; // 1 second
ts.tv_usec = 0;
while (1) {
// select setup
fd_set fds;
FD_ZERO(&fds);
if (sock != 0)
FD_SET(sock, &fds);
FD_SET(0, &fds);
// wait for data
int nready = select(sock + 1, &fds, (fd_set *) 0, (fd_set *) 0, &ts);
if (nready < 0) {
perror("select. Error");
return 1;
}
else if (nready == 0) {
ts.tv_sec = 1; // 1 second
ts.tv_usec = 0;
}
else if (sock != 0 && FD_ISSET(sock, &fds)) {
// start by reading a single byte
int rv;
if ((rv = recv(sock , buf , 1 , 0)) < 0)
return 1;
else if (rv == 0) {
printf("Connection closed by the remote end\n\r");
return 0;
}
if (buf[0] == CMD) {
// read 2 more bytes
len = recv(sock , buf + 1 , 2 , 0);
if (len < 0)
return 1;
else if (len == 0) {
printf("Connection closed by the remote end\n\r");
return 0;
}
negotiate(sock, buf, 3);
}
else {
len = 1;
buf[len] = '\0';
printf("%s", buf);
fflush(0);
}
}
else if (FD_ISSET(0, &fds)) {
buf[0] = getc(stdin); //fgets(buf, 1, stdin);
if (send(sock, buf, 1, 0) < 0)
return 1;
if (buf[0] == '\n') // with the terminal in raw mode we need to force a LF
putchar('\r');
}
}
close(sock);
return 0;
}
While the server code is :
enter code here
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <cstring>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <netdb.h>
int main(int argc , char *argv[])
{
int socket_desc , new_socket , c;
struct sockaddr_in server ,client;
char *message;
//create socket;
socket_desc = socket(AF_INET , SOCK_STREAM , 0);
if (socket_desc == -1)
{printf("Could not create socket");
}
//prepare sock addr structure
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons( 8888 );
//bind
if(bind(socket_desc, (struct sockaddr *)&server , sizeof(&server)) < 0)
{
printf("bind failed");
}
printf("Bind done");
//Listen
listen(socket_desc , 3);
//accept incoming connection
printf("Waiting for incoming connection ... ");
c =sizeof(struct sockaddr_in);
new_socket = accept(socket_desc, (struct sockaddr *)&client,sizeof(&client));
while(new_socket < 0);
{
puts("Connection Accepted");
message = "Hello Client ...Recieved your message \n";
write(new_socket , message , strlen(message));
}
if (new_socket < 0)
{
perror("accept failed");
return 1;
}
return 0;
}
On executing the programs from command line :
./server 8000
./telnet_client 127.0.0.1 8000
The telnet client gives the error "Connect failed.Error:Connection refused"
Kindly help how to successfully execute the program
You are listening on 8888 port but trying to connect to 8000. Although you are passing 8000 parameter to server program you don't do anything with it. To correct this don't hard code
server.sin_port = htons( 8888 );
but instead process parameters passed to the program
if ( argc != 2)
err_quit("usage: server <port>"); // or maybe use some default
//...
server.sin_port = htons( atoi( argv[1]) );
in the server
int port = 8888;
...
if (argc < 1 || argc > 2) {
printf("Usage: %s [port(default=8888)] \n", argv[0]);
return 1;
}
port = (argc == 2) ? atoi(argv[1]);
...
server.sin_port = htons(port);
...

how to establish sip session in .c programming between client and server

this is client server application I want to establish SIP (session initiation protocol) between client and server.
So please anyone guide me how can I do this.
server.c:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include <signal.h>
#include <netinet/tcp.h>
#define MYPORT 3490 // the port users will be connecting to
#define BACKLOG 10 // how many pending connections queue will hold
#define MAXDATASIZE 100
void str_server(int);
void sigchld_handler(int s)
{
while(waitpid(-1, NULL, WNOHANG) > 0);
}
int main(void)
{
int sockfd, numbytes,new_fd, optlen; // listen on sock_fd, new connection on new_fd
struct sockaddr_in my_addr; // my address information
struct sockaddr_in their_addr; // connector's address information
struct tcp_info info;
socklen_t sin_size;
struct sigaction sa;
char buf[MAXDATASIZE];
int yes=1;
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("socket");
exit(1);
}
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) {
perror("setsockopt");
exit(1);
}
my_addr.sin_family = AF_INET; // host byte order
my_addr.sin_port = htons(MYPORT); // short, network byte order
my_addr.sin_addr.s_addr = INADDR_ANY; // automatically fill with my IP
memset(my_addr.sin_zero, '\0', sizeof my_addr.sin_zero);
if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof my_addr) == -1) {
perror("bind");
exit(1);
}
if (listen(sockfd, BACKLOG) == -1) {
perror("listen");
exit(1);
}
sa.sa_handler = sigchld_handler; // reap all dead processes
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_RESTART;
if (sigaction(SIGCHLD, &sa, NULL) == -1) {
perror("sigaction");
exit(1);
}
while(1) { // main accept() loop
sin_size = sizeof their_addr;
getchar();
if ((new_fd = accept(sockfd, (struct sockaddr *)&their_addr, \
&sin_size)) == -1) {
perror("accept");
continue;
}
printf("server: got connection from %s\n", \
inet_ntoa(their_addr.sin_addr));
if (!fork()) { // this is the child process
close(sockfd); // child doesn't need the listener
if ((numbytes=recv(new_fd, buf, MAXDATASIZE-1, 0)) == -1) {
perror("recv");
exit(1);
}
buf[numbytes] = '\0';
printf("Received From Client: %s\n",buf);
str_server(sockfd);
FILE *fp = fopen( "adventure.mpg", "rb" );
//if(!fork())
// execlp("gedit", "gedit", "SIPFILE.txt", NULL);
//system("popen /home/umair/Documents/CurrentData/SIPFILE.txt");
//ShellExecute(GetDesktopWindow(), "open","ls /home/umair/Documents
/CurrentData/SIPFILE.txt",NULL, NULL, SW_SHOW);
if (send(new_fd, "Hello, world!\n", 14, 0) == -1)
perror("send");
close(new_fd);
exit(0);
}
close(new_fd); // parent doesn't need this
}
return 0;
}
void str_server(int sock)
{
char buf[1025];
const char* filename = "test.text";
FILE *file = fopen(filename, "rb");
if (!file)
{
printf("Can't open file for reading");
return;
}
while (!feof(file))
{
int rval = fread(buf, 1, sizeof(buf), file);
if (rval < 1)
{
printf("Can't read from file");
fclose(file);
return;
}
int off = 0;
do
{
int sent = send(sock, &buf[off], rval - off, 0);
if (sent < 1)
{
// if the socket is non-blocking, then check
// the socket error for WSAEWOULDBLOCK/EAGAIN
// (depending on platform) and if true then
// use select() to wait for a small period of
// time to see if the socket becomes writable
// again before failing the transfer...
printf("Can't write to socket");
fclose(file);
return;
}
off += sent;
}
while (off < rval);
}
fclose(file);
}
//client.c :
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <netinet/tcp.h>
#define PORT 3490 // the port client will be connecting to
#define MAXDATASIZE 100 // max number of bytes we can get at once
void RecvFile(int , const char* );
FILE *filename;
int main(int argc, char *argv[])
{
int sockfd, numbytes, optlen;
char buf[MAXDATASIZE];
char *message;
struct hostent *he;
struct tcp_info info;
struct sockaddr_in their_addr; // connector's address information
if (argc != 2) {
fprintf(stderr,"usage: client hostname\n");
exit(1);
}
if ((he=gethostbyname(argv[1])) == NULL) { // get the host info
herror("gethostbyname");
exit(1);
}
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("socket");
exit(1);
}
their_addr.sin_family = AF_INET; // host byte order
their_addr.sin_port = htons(PORT); // short, network byte order
their_addr.sin_addr = *((struct in_addr *)he->h_addr);
memset(their_addr.sin_zero, '\0', sizeof their_addr.sin_zero);
if (connect(sockfd, (struct sockaddr *)&their_addr,
sizeof their_addr) == -1) {
perror("connect");
exit(1);
}
printf("connect successfull\n");
/* if (send(sockfd, "Hello, world!\n", 14, 0) == -1)
perror("send");
printf("send successfull\n");
*/
message = "GET /?st=1 HTTP/1.1\r\nHost: www.msn.com\r\n\r\n";
if( send(sockfd , message , strlen(message) , 0) < 0)
{
puts("Send failed");
return 1;
}
puts("Data Send\n");
RecvFile(sockfd , message);
optlen = sizeof(info);
if ((numbytes=recv(sockfd, buf, MAXDATASIZE-1, 0)) == -1) {
perror("recv");
exit(1);
}
buf[numbytes] = '\0';
printf("Received: %s\n",buf);
close(sockfd);
return 0;
}
void RecvFile(int sock, const char* filename)
{
int rval;
char buf[0x1000];
FILE *file = fopen(filename, "wb");
if (!file)
{
printf("Can't open file for writing");
return;
}
do
{
rval = recv(sock, buf, sizeof(buf), 0);
if (rval < 0)
{
// if the socket is non-blocking, then check
// the socket error for WSAEWOULDBLOCK/EAGAIN
// (depending on platform) and if true then
// use select() to wait for a small period of
// time to see if the socket becomes readable
// again before failing the transfer...
printf("Can't read from socket");
fclose(file);
return;
}
if (rval == 0)
break;
int off = 0;
do
{
int written = fwrite(&buf[off], 1, rval - off, file);
if (written < 1)
{
printf("Can't write to file");
fclose(file);
return;
}
off += written;
}
while (off < rval);
}
while (!feof(file));
fclose(file);
}
Any Suggestion?
I am not sure what you are trying to do with SIP, but the code snippet you've provided shows only establishing a TCP/IP connection. If you intend to do a SIP server-client application, I suggest that you look for a library to help you along the way.
One that I know of that is very complete is called Sofia SIP:
http://sofia-sip.sourceforge.net/
It's written by Nokia for Linux in C language.
Source code is available here: http://gitorious.org/sofia-sip/sofia-sip/trees/master
(Older http://sourceforge.net/p/sofia-sip/git/ci/master/tree/)
you can learn about sipp scenarios and message passing through this utility and its documentation.

socket programming( server and client on the same computer) something wrong with connection

I'm new to socket programming and I have this client that tries to connect to a server on the same computer. But the server hangs there after bind or accept—cause bind seems to be right but no output. I know that the server works because another client can connect just fine and the client seems to have done that. What causes the server to not see this incoming connection? I'm at the end of my wits here.
And I haven't been used to programming on Mac, so thank you so much for your patience if I have made some foolish mistakes.
My code is as follows:
server.cpp
using namespace std;
#include<iostream>
#include <netinet/in.h>
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#define PORT 8888
#define BACKLOG 20
//#define DEST_IP "127.0.0.1"
int process_conn_server(int s)
{
ssize_t size =0;
char buffer[1024];
for( ; ; )
{
size = read(s,buffer,1024);
if(size == 0)
{
return 0;
}
}
sprintf(buffer, "%d bytes altogether\n", (int)size);
write(s, buffer,strlen(buffer)+1);
return 0;
}
int main(int argc,char *argv[])
{
//cout<<"?";
int ss, sc, r, err;
struct sockaddr_in server_addr;
struct sockaddr_in client_addr;
int opt=1;
pid_t pid;
bzero(&server_addr, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
server_addr.sin_port = htons(PORT);
ss = socket(AF_INET, SOCK_STREAM, 0);
if(ss<0)
{
cout<<"[process infro]socket error"<<endl;
return -1;
}
cout<<"[process infro]socket successful"<<endl;
r = setsockopt(ss, SOL_SOCKET,SO_REUSEADDR, (void*)&opt,sizeof(opt));
if (r == -1)
{
perror("setsockopt(listen)");
return 0;
}
cout<<"[process infro]sockopt successful"<<endl;
cout<<"?";
err = bind(ss, (struct sockaddr*) &server_addr, sizeof( server_addr));
cout<<"err";
if(err < 0)
{
cout<<"[process infro]bind error"<<endl;
return -1;
}
cout<<"[process infro]bind successful";
err=listen(ss, BACKLOG);
if(err <0)
{
cout<<"[process infro]listen error"<<endl;
return -1;
}
cout<<"[process infro]lisen successful";
for( ; ; )
{
int addrlen = sizeof(struct sockaddr);
sc = accept(ss, (struct sockaddr*)&client_addr, (socklen_t *)&addrlen);
if(sc < 0)
{
continue;
}
pid = fork();
if (pid == 0)
{
close(ss);
process_conn_server(sc);
}
else
{
close(sc);
}
}
//opt=0;
//setsockopt(ss,SOL_SOCKET,SO_REUSEADDR,(void*)&opt,sizeof(len));
}
client.cpp
using namespace std;
#include<iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <time.h>
#include <arpa/inet.h>
#include <fstream.h>
#define PORT 8888
#define DEST_IP "127.0.0.1"
void process_conn_client(int s)
{
ssize_t size = 0;
char buffer[1024];
//read from the file to be sent
fstream outfile("programm.txt",ios::in|ios::out);
if (outfile.fail())
{
printf("[process infro]cannot open the file to be sent\n");
return ;
}
printf("[process infro]successfully open the file to be sent\n");
while(!outfile.eof())
{
outfile.getline(buffer,1025,'\n');
write(s,buffer,1024);
size = read(s, buffer, 1024);
if(size = 0)
{
return ;
}
//write to the server
write(s,buffer,size);
//get response from the server
size=read(s,buffer,1024);
write(1,buffer,size);
}
outfile.close(); //关闭文件
}
int main(int argc,char *argv[])
{
int s;
struct sockaddr_in server_addr;
bzero(&server_addr, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = inet_addr(DEST_IP);
server_addr.sin_port = htons(PORT);
s = socket(AF_INET, SOCK_STREAM, 0);
if(s < 0)
{
cout<<"[process infro]socke error"<<endl;
return -1;
}
cout<<"[process infro] socket built successfully\n";
//inet_pton(AF_INET, argv[1], &server_addr.sin_addr);
connect(s, (struct sockaddr*)&server_addr, sizeof(struct sockaddr));
cout<<"[process infor] connected\n";
process_conn_client(s);
close(s);
return 0;
}
This may be unrelated.... but it won't fit in a comment...
In your server you do this:
int process_conn_server(int s)
{
ssize_t size =0;
char buffer[1024];
for( ; ; )
{
// keep reading until read returns 0
size = read(s,buffer,1024);
if(size == 0)
{
return 0;
}
}
sprintf(buffer, "%d bytes altogether\n", (int)size);
write(s, buffer,strlen(buffer)+1);
return 0;
}
In your client you do this:
void process_conn_client(int s)
{
ssize_t size = 0;
char buffer[1024];
//read from the file to be sent
fstream outfile("programm.txt",ios::in|ios::out);
if (outfile.fail())
{
printf("[process infro]cannot open the file to be sent\n");
return ;
}
printf("[process infro]successfully open the file to be sent\n");
while(!outfile.eof())
{
outfile.getline(buffer,1025,'\n');
// write to server?
write(s,buffer,1024);
// read from server?
size = read(s, buffer, 1024);
if(size = 0)
{
return ;
}
//write to the server
write(s,buffer,size);
//get response from the server
size=read(s,buffer,1024);
write(1,buffer,size);
}
outfile.close();
}
It's a bit hard to follow because of your variable names, but it looks like your client is working under the assumption that your server will send back a response for every chunk of data received, which isn't the case. You server doesn't appear to have changed the accepted socket to non-blocking, so it's going to block on the read call until there is some data to read (it's never going to get 0)...
Are you sure it's failing before this point? Do you have some sample output?
Aso, in your call to accept, you pass addrlen...
int addrlen = sizeof(struct sockaddr);
I think this should be:
int addrlen = sizeof(struct sockaddr_in); /* sizeof(client_addr) */