概述
socket编程详解(二)——客户端
- 写在前面
- client函数api
- connect ()函数
- send()函数和recv()函数
- demo1示例
- demo2示例
- demo3示例
写在前面
上一小节我们讲了socket编程服务器端,也简单说了各个函数的使用说明,下面我们看看客户端是怎样完成的,以及互相聊天的实现。。。
传送:socket编程详解(一)——服务器端
首先我们再贴贴上一小节的图:
客户端编程的文字步骤:
1:加载套接字库,创建套接字(WSAStartup()/socket());
2:向服务器发出连接请求(connect());
3:和服务器端进行通信(send()/recv());
4:关闭套接字,关闭加载的套接字库(closesocket()/WSACleanup())。
client函数api
connect ()函数
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
补充第二套收发函数:send和recv函数
send()函数和recv()函数
客户端比较简单连接上收发消息就可以了。。。。
demo1示例
client.c
#include <stdio.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <unistd.h>
#include <string.h>
int main(){
int c_fd;
struct sockaddr_in c_addr;
char readBuf[128];
char *msg = "msg from client";
//void *memset(void *s, int c, size_t n);
memset(&c_addr,0,sizeof(struct sockaddr_in));
//1.scoket
//int socket(int domain, int type, int protocol);
c_fd = socket(AF_INET,SOCK_STREAM,0);
if(c_fd == -1){
perror("socket");
exit(-1);
}
c_addr.sin_family = AF_INET;
c_addr.sin_port = htons(8089);
inet_aton("192.168.2.40",&c_addr.sin_addr);
//2.connect
//int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
if(connect(c_fd,(struct sockaddr *)&c_addr,sizeof(struct sockaddr)) == -1){
perror("connect");
exit(-1);
}
//3.write
//ssize_t write(int fd, const void *buf, size_t count);
write(c_fd,msg,128);
//4.read
//ssize_t read(int fd, void *buf, size_t count);
int n_read = read(c_fd,readBuf,128);
if(n_read == -1){
perror("read");
}else{
printf("msg:%d,%sn",n_read,readBuf);
}
return 0;
}
目前基本的框架已经完成了,不足的是只能发送一次消息,不能够持续性的聊天,我们再改进下。。。
demo2示例
tserver.c服务器端
int main(int argc,char **argv){
int s_fd;
int c_fd;
struct sockaddr_in s_addr;
struct sockaddr_in c_addr;
char readBuf[128];
//char *msg = "msg from server";
char msg[128] = {0};
//void *memset(void *s, int c, size_t n);
memset(&s_addr,0,sizeof(struct sockaddr_in));
memset(&c_addr,0,sizeof(struct sockaddr_in));
//加上参数判断
if(argc != 3){
printf("Parameter incomplete!n");
exit(-1);
}
//1.scoket
//int socket(int domain, int type, int protocol);
s_fd = socket(AF_INET,SOCK_STREAM,0);
if(s_fd == -1){
perror("socket");
exit(-1);
}
s_addr.sin_family = AF_INET;
s_addr.sin_port = htons(atoi(argv[2]));
inet_aton(argv[1],&s_addr.sin_addr);
//2.bind
//int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
bind(s_fd,(struct sockaddr *)&s_addr,sizeof(struct sockaddr_in));
//3.listen
//int listen(int sockfd, int backlog);
listen(s_fd,10);
//4.accept
//int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
int len = sizeof(struct sockaddr_in);
while(1){//监听后不断的接收连接
c_fd = accept(s_fd,(struct sockaddr *)&c_addr,&len);
if(c_fd == -1){
perror("accept");
exit(-1);
}
printf("connect:%sn",inet_ntoa(c_addr.sin_addr));
if(fork() == 0){
//创建子进程,父进程等待连接消息,子进程来完成读写操作,写和读不断循环,随时收发,同样的客户端也要循环匹配
if(fork() == 0){
while(1){
//6.write
//ssize_t write(int fd, const void *buf, size_t count);
memset(msg,0,sizeof(msg));
printf("input: ");
gets(msg);
write(c_fd,msg,strlen(msg));
}
}
while(1){
//5.read
//ssize_t read(int fd, void *buf, size_t count);
memset(readBuf,0,sizeof(readBuf));
int n_read = read(c_fd,readBuf,128);
if(n_read == -1){
perror("read");
}else{
printf("msg from client:%d,%sn",n_read,readBuf);
}
}
}
}
return 0;
}
tclient.c客户端
int main(int argc,char **argv){
int c_fd;
struct sockaddr_in c_addr;
char readBuf[128];
//char *msg = "msg from client";
char msg[128] = {0};
//void *memset(void *s, int c, size_t n);
memset(&c_addr,0,sizeof(struct sockaddr_in));
//加上参数判断
if(argc != 3){
printf("Parameter incomplete!n");
exit(-1);
}
//1.scoket
//int socket(int domain, int type, int protocol);
c_fd = socket(AF_INET,SOCK_STREAM,0);
if(c_fd == -1){
perror("socket");
exit(-1);
}
c_addr.sin_family = AF_INET;
c_addr.sin_port = htons(atoi(argv[2]));
inet_aton(argv[1],&c_addr.sin_addr);
//2.connect
//int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
if(connect(c_fd,(struct sockaddr *)&c_addr,sizeof(struct sockaddr)) == -1){
perror("connect");
exit(-1);
}
while(1){
//3.write
//ssize_t write(int fd, const void *buf, size_t count);
if(fork() == 0){
while(1){
memset(msg,0,sizeof(msg));
printf("input: ");
gets(msg);
write(c_fd,msg,strlen(msg));
}
}
while(1){
//4.read
//ssize_t read(int fd, void *buf, size_t count);
memset(readBuf,0,sizeof(readBuf));
int n_read = read(c_fd,readBuf,128);
if(n_read == -1){
perror("read");
}else{
printf("msg from server:n%sn",readBuf);
}
}
}
return 0;
}
关于上面的父子进程的创建:
运行结果如下:
上面的只是针对单个客户端,那么实现多个客户端的消息发送呢???
仅限客户端消息发送哈。。。。
demo3示例
dserver.c服务器端
#include <stdio.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <unistd.h>
#include <string.h>
int main(int argc,char **argv){
int s_fd;
int c_fd;
struct sockaddr_in s_addr;
struct sockaddr_in c_addr;
char readBuf[128];
//char *msg = "msg from server";
char msg[128] = {0};
int mark = 0;
//void *memset(void *s, int c, size_t n);
memset(&s_addr,0,sizeof(struct sockaddr_in));
memset(&c_addr,0,sizeof(struct sockaddr_in));
if(argc != 3){
printf("Parameter incomplete!n");
exit(-1);
}
//1.scoket
//int socket(int domain, int type, int protocol);
s_fd = socket(AF_INET,SOCK_STREAM,0);
if(s_fd == -1){
perror("socket");
exit(-1);
}
s_addr.sin_family = AF_INET;
s_addr.sin_port = htons(atoi(argv[2]));
inet_aton(argv[1],&s_addr.sin_addr);
//2.bind
//int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
bind(s_fd,(struct sockaddr *)&s_addr,sizeof(struct sockaddr_in));
//3.listen
//int listen(int sockfd, int backlog);
listen(s_fd,10);
//4.accept
//int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
int len = sizeof(struct sockaddr_in);
while(1){
c_fd = accept(s_fd,(struct sockaddr *)&c_addr,&len);
if(c_fd == -1){
perror("accept");
exit(-1);
}
mark++;
printf("connect:%sn",inet_ntoa(c_addr.sin_addr));
if(fork() == 0){
if(fork() == 0){
while(1){
//6.write
//ssize_t write(int fd, const void *buf, size_t count);
sprintf(msg,"welcome No.%d client",mark);
write(c_fd,msg,strlen(msg));
sleep(10);
}
}
while(1){
//5.read
//ssize_t read(int fd, void *buf, size_t count);
memset(readBuf,0,sizeof(readBuf));
int n_read = read(c_fd,readBuf,128);
if(n_read == -1){
perror("read");
}else{
printf("msg from client:n%sn",readBuf);
}
}
}
}
return 0;
}
客户端不用改变,只需要在服务器端打印客户端号即可
效果比较鸡肋,记录下来看看。。。。
ending!
最后
以上就是腼腆蜻蜓为你收集整理的socket编程详解(二)——客户端的全部内容,希望文章能够帮你解决socket编程详解(二)——客户端所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复