一、TCP通信,只发送一次就结束程序
功能描述:
1、服务端一次只能连接一个客户端。 2、客户端只能向服务端发送一次消息,消息返回后客户端和服务器程序结束。 3、客户端向服务端发送一个字符串,服务端将字符串改为大写后返还到客户端。
步骤一:
依次编译客户端和服务器源程序,然后使用ifconfig命令查看虚拟机IP地址,用于之后客户端使用这个IP地址访问服务器。
步骤二:
打开两个终端,客户端服务器各一个,先运行服务器端,再运行客户端,全部运行之后便可以通过客户端向服务器发送消息了。
客户端源码:
#include<stdio.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<string.h>
#include<stdlib.h>
#define SERVPORT 8080
int main(int argc,int *argv[])
{
int sockfd;
int recv_len;
struct sockaddr_in servaddr,cliaddr;
char sendline[100];
char recvline[100];
if(argc != 2)
{
printf("need server address\n");
exit(0);
}
sockfd = socket(AF_INET,SOCK_STREAM,0);
bzero(&servaddr,sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(SERVPORT);
servaddr.sin_addr.s_addr = inet_addr(argv[1]);
connect(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr));
while(fgets(sendline,100,stdin) != NULL)
{
sendto(sockfd,sendline,strlen(sendline),0,
(struct sockaddr *)&servaddr,sizeof(servaddr));
recv_len = recvfrom(sockfd,recvline,100,0,NULL,NULL);
recvline[recv_len] = '\0';
fputs(recvline,stdout);
}
close(sockfd);
return 0;
}
服务器源码:
#include<stdio.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<unistd.h>
#include<string.h>
#include<ctype.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<fcntl.h>
#define SERVPORT 8080
int main(int argc)
{
int listenfd,connfd,recv_len,send_len;
socklen_t clilen;
struct sockaddr_in servaddr,cliaddr;
char buff[100];
listenfd = socket(AF_INET,SOCK_STREAM,0);
bzero(&servaddr,sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(SERVPORT);
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
bind(listenfd,(struct sockaddr *)&servaddr,sizeof(servaddr));
printf("bind is sucessifully!\n");
listen(listenfd,10);
connfd = accept(listenfd,(struct sockaddr *)&cliaddr,&clilen);
printf("connect sucessifully!\n");
recv_len = recv(connfd,buff,100,0);
buff[recv_len] = '\0';
printf("received the following:\n");
printf("%s",buff);
for(int i=0; i<recv_len; i++)
{
buff[i] = toupper(buff[i]);
}
send_len = send(connfd,buff,recv_len,0);
close(listenfd);
return 0;
}
二、TCP通信,服务端与客户端实现多次通信
功能描述:
1、服务端一次只能连接一个客户端。 2、客户端可以向服务端多次发送消息,直到客户端发送一个空的消息后,客户端和服务器程序结束。 3、客户端向服务端发送一个字符串,服务端将字符串改为大写后返还到客户端。
步骤同第一个(省)
客户端源码:
#include<stdio.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<string.h>
#include<stdlib.h>
#include<arpa/inet.h>
#include<unistd.h>
#define SERVPORT 8080
int main(int argc,char *argv[])
{
int sockfd;
int recv_len;
struct sockaddr_in servaddr,cliaddr;
char sendline[100];
char recvline[100];
if(argc != 2)
{
printf("need server address\n");
exit(0);
}
sockfd = socket(AF_INET,SOCK_STREAM,0);
bzero(&servaddr,sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(SERVPORT);
servaddr.sin_addr.s_addr = inet_addr(argv[1]);
connect(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr));
printf("send to service : ");
while(fgets(sendline,100,stdin) != NULL)
{
send(sockfd,sendline,strlen(sendline),0);
recv_len = recv(sockfd,recvline,100,0);
recvline[recv_len] = '\0';
printf("back from service: ");
fputs(recvline,stdout);
printf("------------------------------\n");
printf("send to service : ");
}
close(sockfd);
return 0;
}
服务器源码:
#include<stdio.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<unistd.h>
#include<string.h>
#include<ctype.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<fcntl.h>
#define SERVPORT 8080
int main(int argc)
{
int listenfd,connfd,recv_len,send_len;
socklen_t clilen;
struct sockaddr_in servaddr,cliaddr;
char buff[100];
listenfd = socket(AF_INET,SOCK_STREAM,0);
bzero(&servaddr,sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(SERVPORT);
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
bind(listenfd,(struct sockaddr *)&servaddr,sizeof(servaddr));
printf("bind is sucessifully! \n");
listen(listenfd,10);
printf("Waiting for clients to connect...\n");
connfd = accept(listenfd,(struct sockaddr *)&cliaddr,&clilen);
printf("%d connect sucessifully!\n",connfd);
while(1)
{
recv_len = recv(connfd,buff,100,0);
if(recv_len == 0)
{
break;
}
buff[recv_len] = '\0';
printf("received the following:\n");
printf("%s",buff);
for(int i=0; i<recv_len; i++)
{
buff[i] = toupper(buff[i]);
}
send_len = send(connfd,buff,recv_len,0);
}
close(listenfd);
return 0;
}
三、多线程实现TCP-Socket通信
功能描述:
1、服务端可以同时连接多个客户端。 2、多个客户端并发运行,同时实现与服务器的通信。 3、客户端向服务端发送一个字符串,服务端将字符串改为大写后返还到客户端。 4、客户端全部关闭时,服务器仍然运行,当有新的客户端连接时,继续工作。
步骤一:
依次编译客户端和服务器源程序,然后使用ifconfig命令查看虚拟机IP地址,用于之后客户端使用这个IP地址访问服务器。
步骤二:
然后打开三个终端,一个为服务器,两个为客户端,
步骤三:
照着下图,先运行服务器,再运行客户端,全部运行之后便可以通过客户端向服务器发送消息了。
效果展示:
客户端源码:
#include<stdio.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<string.h>
#include<stdlib.h>
#include<arpa/inet.h>
#include<unistd.h>
#define SERVPORT 8080
int main(int argc,char *argv[])
{
int sockfd;
int recv_len;
struct sockaddr_in servaddr,cliaddr;
char sendline[100];
char recvline[100];
if(argc != 2)
{
printf("need server address\n");
exit(0);
}
sockfd = socket(AF_INET,SOCK_STREAM,0);
bzero(&servaddr,sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(SERVPORT);
servaddr.sin_addr.s_addr = inet_addr(argv[1]);
connect(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr));
printf("send to service : ");
while(fgets(sendline,100,stdin) != NULL)
{
send(sockfd,sendline,strlen(sendline),0);
recv_len = recv(sockfd,recvline,100,0);
recvline[recv_len] = '\0';
printf("back from service: ");
fputs(recvline,stdout);
printf("------------------------------\n");
printf("send to service : ");
}
close(sockfd);
return 0;
}
服务器源码
#include<stdio.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<unistd.h>
#include<string.h>
#include<ctype.h>
#include<arpa/inet.h>
#include<fcntl.h>
#include<pthread.h>
#define SERVPORT 8080
#define CONNECTNUM 10
void thread_fun(void * cconnfd)
{
int connfd =*(int *)cconnfd;
int recv_len,send_len;
char buff[100];
while(1)
{
recv_len = recv(connfd,buff,100,0);
if(recv_len == 0)
{
break;
}
buff[recv_len] = '\0';
printf("received from client%d the following:\n",connfd);
printf("%s",buff);
for(int i=0; i<recv_len; i++)
{
buff[i] = toupper(buff[i]);
}
send_len = send(connfd,buff,recv_len,0);
printf("have replied client%d ,over. \n ",connfd);
printf("------------------------------ \n");
}
pthread_exit(NULL);
}
int main(int argc)
{
int listenfd,connfd,recv_len,send_len;
socklen_t clilen;
struct sockaddr_in servaddr,cliaddr;
char buff[100];
pthread_t pid[CONNECTNUM];
listenfd = socket(AF_INET,SOCK_STREAM,0);
bzero(&servaddr,sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(SERVPORT);
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
bind(listenfd,(struct sockaddr *)&servaddr,sizeof(servaddr));
printf("bind is sucessifully! \n");
listen(listenfd,10);
printf("Waiting for clients to connect...\n");
for(int j =0; j<CONNECTNUM; j++)
{
connfd = accept(listenfd,(struct sockaddr *)&cliaddr,&clilen);
printf("%d connect sucessifully!\n",connfd);
pthread_create(&pid[j],NULL,(void *)thread_fun,&connfd);
}
close(listenfd);
return 0;
}
|