I am fairly new to socket programming. I saw a tutorial and tried implementing the programs in my Linux machine. The codes are :
CLIENT :
int main() {
char buf[256] = "In client";
// create the socket
int sock;
sock = socket(AF_INET, SOCK_STREAM, 0);
//setup an address
struct sockaddr_in server_address;
server_address.sin_family = AF_INET;
server_address.sin_addr.s_addr = INADDR_ANY;
server_address.sin_port = htons(9002);
int status = connect(sock, (struct sockaddr *) &server_address, sizeof(server_address));
if(status == -1)
{
printf("There Was an error!");
}
recv(sock, buf, sizeof(buf), 0);
printf("\n %s \n", buf);
close(sock);
return 0;
}
SERVER:
int main() {
char server_message[256] = "You have reached the server!";
// create the server socket
int server_socket;
server_socket = socket(AF_INET, SOCK_STREAM, 0);
// define the server address
struct sockaddr_in server_address;
server_address.sin_family = AF_INET;
server_address.sin_port = htons(9002);
server_address.sin_addr.s_addr = INADDR_ANY;
// bind the socket to our specified IP and port
bind(server_socket, (struct sockaddr*) &server_address, sizeof(server_address));
listen(server_socket, 5);
int client_socket;
client_socket = accept(server_socket, NULL, NULL);
// send the message
send(client_socket, server_message, sizeof(server_message), 0);
// close the socket
close(server_socket);
return 0;
}
The code is self-explanatory. When I run the server and then the client, for the first time, it works. But when I do it again, just after the previous one, the Client gives the message - There Was an error!, that means the connection is not happening.
Can anyone help why is this occurring?
Thanks in advance!
You should be checking for errors for all system calls in your server. I'm guessing that your bind is failing, because the port is "already in use". The reason for this is that the connection from the previous instance of the server lingers for a while in the operating system's connection table.
You want to use setsockopt with SO_REUSEADDR to avoid the bind failure. Specifically, add this prior to the bind call.
int reuse = 1;
if (setsockopt(server_socket, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuse, sizeof(reuse)) < 0)
perror("setsockopt(SO_REUSEADDR) failed");
(And do check errors. Makes debugging these kinds of things much easier if you know when something fails. Also, use perror or strerror(errno) in order to find out exactly why it failed -- not just that it failed.)
Check out my whole code here and see how it runs.
This is the server
int main(){
SOCKET s, newsocket;
struct sockaddr_in server, client;
int receiving;
char clientMessage[2000], *message;
if((s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET){
printf("socker error at %d", GetLastError());
}else{
puts("socket created");
}
server.sin_addr.s_addr = inet_addr("127.0.0.1");
server.sin_family = AF_INET;
server.sin_port = htons(8080);
if(bind(s, (struct sockaddr*)&server, sizeof(server)) < 0){
printf("err at binding %d", GetLastError());
}else{
puts("binded.");
}
listen(s, 3);
puts("listening to connections...");
int c = sizeof(struct sockaddr_in);
while((newsocket = accept(s, (struct sockaddr*)&client, &c)) != INVALID_SOCKET){
puts("connection accepted");
//send
message="hello client";
send(newsocket, message, strlen(message), 0);
recv(newsocket, clientMessage, 50, 0);
puts(clientMessage);
}
puts("waiting for a machine");
if(newsocket == INVALID_SOCKET){
printf("newsocket invalid at %d", GetLastError());
}
getchar();
closesocket(s);
WSACleanup();
}
This is the client
int main(){
SOCKET s;
struct sockaddr_in server;
if((s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET){
printf("socket error At %d", GetLastError());
}else{
puts("socket initialised");
}
server.sin_port = htons(8080);
server.sin_family = AF_INET;
server.sin_addr.s_addr = inet_addr("176.40.201.72");
printf("server values are defined.. \n");
printf("connecting..\n");
if(connect(s, (struct sockaddr*)&server, sizeof(server)) < 0){
printf("connection error %d" , GetLastError());
}else{
puts("connected");
}
return 0;
}
Related
Hey guys I want to send a message of the current date from the server to a client in C.
So I would use a command like this for the client;
Terminal
telnet localhost PORT
What should be the command to send the actual message?
int main(int argc, char *argv[])
{
int socket_desc, client_sock, c, read_size;
struct sockaddr_in server, client;
char client_message[2000];
time_t t = time(NULL);
struct tm tm = *localtime(&t);
socket_desc = socket(AF_INET, SOCK_STREAM, 0);
if (socket_desc == -1)
{
printf("Could not create socket");
}
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons(PORT);
if (bind(socket_desc, (struct sockaddr *)&server, sizeof(server)) < 0)
{
perror("bind failed. Error");
return 1;
}
listen(socket_desc, 3);
puts("Waiting for incoming connections...");
c = sizeof(struct sockaddr_in);
client_sock = accept(socket_desc, (struct sockaddr *)&client, (socklen_t *)&c);
if (client_sock < 0)
{
perror("accept failed");
return 1;
}
puts("Connection accepted");
////////////////////////////////////////////////////
//the actual message here
////////////////////////////////////////////////////
close(socket_desc);
return 0;
}
I made the following addiction and it worked
Is this a proper solution? I don't know how to use send() properly yet.
pid_t child_pid = fork();
if (child_pid == 0)
{
snprintf(client_message, sizeof(client_message), "%s", ctime(&tick));
write(client_sock, client_message, strlen(client_message));
shutdown(client_sock, SHUT_RDWR);
while (read(client_sock, client_message, sizeof(client_message) > 0))
close(client_sock);
}
else if (child_pid > 0)
{
// parent
close(client_sock);
}
else
{
// a fork error occurred, handle and remember to close(connfd)
}
I try to make a Socket client/server bundle running at the same time, passing information to one another. The problem is, after sending the first piece of data from the client, the server returns the answer correctly but becomes stuck on the call to function send(), disabling the ability for the server to receive another data from the client.
I use the following pieces of code in server and client:
Client Code
char requestToSend[1000] = "Some request";
int client_socket;
struct sockaddr_in servaddr;
client_socket = socket(AF_INET, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
servaddr.sin_port = htons(PORT);
connect(client_socket, (SA*)&servaddr, sizeof(servaddr));
char buffer[MAX];
bzero(buffer, sizeof(buffer));
send(server_socket, requestToSend, sizeof(requestToSend), 0);
bzero(requestToSend, sizeof(requestToSend));
while (strcmp(requestToSend, "") == 0) {
recv(server_socket, requestToSend, sizeof(requestToSend), 0);
}
shutdown(client_socket, SHUT_RDWR);
printf("Received: %s", requestToSend); // requestToSend is not the received result!
Server Code
The following code should return "My new result" in response to any request from the client.
while (1) {
int server_socket, client_socket;
struct sockaddr_in server, client;
server_socket = socket(AF_INET, SOCK_STREAM, 0);
if (server_socket == -1) {
printf("Socket creation failed...\n");
} else {
printf("Socket successfully created..\n");
}
bzero(&server, sizeof(server));
server.sin_family = AF_INET;
server.sin_addr.s_addr = htonl(INADDR_ANY);
server.sin_port = htons(PORT);
if ((bind(server_socket, (SA*)&server, sizeof(server))) != 0) {
printf("Socket binding failed...\n");
} else {
printf("Socket successfully bound..\n");
}
if ((listen(server_socket, 5)) != 0) {
printf("Listen failed...\n");
} else {
printf("Server listening..\n");
}
socklen_t len = sizeof(client);
client_socket = accept(server_socket, (SA*)&client, &len);
if (client_socket < 0) {
printf("Server accceptance failed...\n");
} else {
printf("Server acccepted the client..\n");
}
char buffer[MAX];
bzero(buffer, sizeof(buffer));
recv(client_socket, buffer, sizeof(buffer), 0);
strcpy(buffer, "My new result");
send(client_socket, buffer, sizeof(buffer), 0);
shutdown(server_socket, SHUT_RDWR);
}
There are other questions on Stack Overflow mentioning the problem of send() being stuck, but they don't provide an answer to this question.
You should only open and bind the server socket once. The loop should start before the accept() call. And you should close the client socket, not just call shutdown().
When you're sending the reply, you should just send strlen(buffer)+1 bytes, not sizeof(buffer). The latter will send MAX bytes, which will include lots of uninitialized bytes. Adding 1 to strlen() will include the null byte.
int server_socket, client_socket;
struct sockaddr_in server, client;
server_socket = socket(AF_INET, SOCK_STREAM, 0);
if (server_socket == -1) {
printf("Socket creation failed...\n");
} else {
printf("Socket successfully created..\n");
}
bzero(&server, sizeof(server));
server.sin_family = AF_INET;
server.sin_addr.s_addr = htonl(INADDR_ANY);
server.sin_port = htons(PORT);
if ((bind(server_socket, (SA*)&server, sizeof(server))) != 0) {
printf("Socket binding failed...\n");
} else {
printf("Socket successfully bound..\n");
}
if ((listen(server_socket, 5)) != 0) {
printf("Listen failed...\n");
} else {
printf("Server listening..\n");
}
while (1) {
socklen_t len = sizeof(client);
client_socket = accept(server_socket, (SA*)&client, &len);
if (client_socket < 0) {
printf("Server accceptance failed...\n");
} else {
printf("Server acccepted the client..\n");
}
char buffer[MAX];
bzero(buffer, sizeof(buffer));
recv(client_socket, buffer, sizeof(buffer), 0);
strcpy(buffer, "My new result");
send(client_socket, buffer, strlen(buffer)+1, 0);
close(client_socket);
}
The client's recv() loop should loop until it receives 0, which indicates that the server has closed the socket. Each call should append to the buffer, not overwrite it.
char *ptr = requestToSend;
size_t len = sizeof(requestToSend);
int nread;
while ((nread = recv(server_socket, ptr, len, 0)) != 0) {
if (nread < 0) {
perror("recv from server");
exit(1);
}
ptr += nread;
len -= nread;
}
And it should also close the socket, not use shutdown(). shutdown() is generally only used when you want to half-close a socket -- you want to send EOF to the other system, but continue to read its responses.
I'm trying to make a program that uses sockets between a client and a server. In my code below if I comment on the loop while my server receives my message but if I do not comment my client seems not to send my message (finally my server never receives my message). Why ?
Server
int main()
{
message = malloc(sizeof(char));
printf("Waiting for incoming connections ...\n");
sem_init(&lock, 0, 1);
// socket creation
int server_socket;
server_socket = socket(AF_INET, SOCK_STREAM, 0);
// dserver address9002
struct sockaddr_in server_address;
server_address.sin_family = AF_INET;
server_address.sin_port = htons(PORT);
server_address.sin_addr.s_addr = INADDR_ANY;
// bind the socket to IP and port
bind(server_socket, (struct sockaddr*) &server_address, sizeof(server_address));
listen(server_socket, MAX_CONNECTIONS);
int client_socket;
int i = 0;
while(client_counter < 2 && (client_socket = accept(server_socket, NULL,NULL)))
{
client_counter++;
client_sockets[i] = client_socket;
i++;
printf("new client ! \n");
}
//here i create a thread for each client and in this thread there is a while loop with a recv function
}
Client
int socket_connection(char* ip, int port)
{
int network_socket = 0;
struct sockaddr_in server_address;
server_address.sin_family = AF_INET;
server_address.sin_port = htons(port);
server_address.sin_addr.s_addr = inet_addr(ip);
if ((network_socket = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
printf("\n Socket creation error \n");
return -1;
}
int connection_status = connect(network_socket, (struct sockaddr*) &server_address, sizeof(server_address));
if (connection_status < 0)
{
printf("Error while creating / connecting the socket");
return -1;
}
return network_socket;
}
void connect_to_server()
{
char ip[256];
int port;
strcpy(ip, "127.0.0.1");
port = 9002;
// try to connect to the server with the IP and port
int network_socket = socket_connection(ip, port);
char server_reponse[256];
char message[256];
// clean string
memset(server_reponse, 0, sizeof(server_reponse));
recv(network_socket, &server_reponse, sizeof(server_reponse), 0);
if (strcmp(server_reponse, "instruction: make board") == 0)
{
construct_game_board();
show_game_board();
memset(message, 0, sizeof(message));
put_ship(message);
printf("Finish to make board\n");
}
printf("Reponse send to socket %d: %zu\n",network_socket, send(network_socket, message, strlen(message), 0));
while (1) {
printf("Before recv\n");
printf("Reponse recv : %zu\n", recv(network_socket, server_reponse, sizeof(server_reponse), 0));
printf("After recv\n");
}
In my console when i launch i have : Reponse send to socket 3: 0 and Before recv
First try with socket prog. any help why I get this error? This my server side code, till the part of bind (exluding listen etc)
thnx in advance
int main(){
unsigned int s; //returned by socket()
int port; //port number
int n; //fore read() & write()
int newsockfd; //returned by accept()
struct sockaddr_in server , client;
socklen_t clntLen; // Length of client address data structure
s = socket(AF_UNIX, SOCK_STREAM,0);
if(s==-1){
perror("Socket was not created\n");
return 0;
}
printf("Socket successfully created! ID: %d\n",s);
//sockaddr_in structure
memset( &server, 0, sizeof(server) ); // Zero structure
server.sin_family = AF_INET;
server.sin_addr.s_addr = htonl(INADDR_ANY);
server.sin_port = htons( 8888 );
//Bind
if( bind(s,(struct sockaddr *)&server , sizeof(server)) < 0){
//print the error message
perror("Bind failed! Error");
return 1;
}
printf("Bind completed successfully\n");
}
Use AF_INET instead of AF_UNIX in the call to socket().
I created a server socket in C. This is the most basic stuff like what you would fine in a simple TCP server example. Server code is below. I also created a client socket that runs on the host machine. Code also below. However, for some reason the client is not able to connect to the server. The IP address I used is the same as the one under the entry eth0 from the "ip addr" command. The network adapter of the VM is a bridged connection.
The exact same code works when both client and server run on the same machine (the host).
Thank you!
Server code:
int sockfd;
int clientfd;
struct sockaddr_in self;
struct sockaddr_in client_addr;
int addrlen = sizeof (client_addr);
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
perror("Socket");
return EXIT_FAILURE;
}
printf("Socket descriptor is: %d\n", sockfd);
memset(&self, 0, sizeof (self));
self.sin_family = AF_INET;
self.sin_port = htons(MY_PORT);
self.sin_addr.s_addr = INADDR_ANY;
if (bind(sockfd, (struct sockaddr*) &self, sizeof (self)) != 0) {
perror("socket--bind");
return EXIT_FAILURE;
}
if (listen(sockfd, 20) != 0) {
perror("socket--listen");
return EXIT_FAILURE;
}
clientfd = accept(sockfd, (struct sockaddr*) &client_addr, &addrlen);
printf("%s:%d connected\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
Client Code:
int sock;
struct sockaddr_in server;
//struct sockaddr_in client;
struct hostent *hp;
//char buf[BUFFER_SIZE];
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
die(6, "Opening stream socket");
printf("Client socket file descriptor is: %d\n", sock);
memset(&server, (char) 0, sizeof (server));
server.sin_family = AF_INET;
hp = gethostbyname(host_name);
if (!hp) {
//sprintf(buf, "%s: unknown host\n", host_name);
die(8, "%s: unknown host\n", host_name);
}
memcpy(hp->h_addr, &server.sin_addr, hp->h_length);
server.sin_port = htons((u_short) SERVER_PORT);
/* Try to connect */
if ((connect(sock, (struct sockaddr *) &server, sizeof (server))) < 0)
die(7, "%s", "Failed to connect stream socket\n");